OSDN Git Service

A foolish consistency is the hobgoblin of little minds.
authorDan Bornstein <danfuzz@android.com>
Tue, 5 May 2009 18:15:23 +0000 (11:15 -0700)
committerDan Bornstein <danfuzz@android.com>
Tue, 5 May 2009 20:08:18 +0000 (13:08 -0700)
    -- Ralph Waldo Emerson

dx/src/com/android/dx/ssa/SsaBasicBlock.java
dx/src/com/android/dx/ssa/SsaConverter.java
dx/src/com/android/dx/ssa/SsaRenamer.java
dx/src/com/android/dx/ssa/back/FirstFitLocalCombiningAllocator.java
dx/src/com/android/dx/ssa/back/LivenessAnalyzer.java

index 7b78c46..378780d 100644 (file)
@@ -49,7 +49,7 @@ public final class SsaBasicBlock {
      */
     public static final Comparator<SsaBasicBlock> LABEL_COMPARATOR =
         new LabelComparator();
-    
+
     /** {@code non-null;} insn list associated with this instance */
     private ArrayList<SsaInsn> insns;
 
@@ -83,14 +83,14 @@ public final class SsaBasicBlock {
     /** list of dom children */
     private final ArrayList<SsaBasicBlock> domChildren;
 
-    /** 
-     * The number of moves added to the end of the block during the
+    /**
+     * the number of moves added to the end of the block during the
      * phi-removal process. Retained for subsequent move scheduling.
      */
     private int movesFromPhisAtEnd = 0;
 
-    /** 
-     * The number of moves added to the beginning of the block during the
+    /**
+     * the number of moves added to the beginning of the block during the
      * phi-removal process. Retained for subsequent move scheduling.
      */
     private int movesFromPhisAtBeginning = 0;
@@ -109,7 +109,7 @@ public final class SsaBasicBlock {
 
     /**
      * Creates a new empty basic block.
-     * 
+     *
      * @param basicBlockIndex index this block will have
      * @param ropLabel original rop-form label
      * @param parent method of this block
@@ -133,8 +133,8 @@ public final class SsaBasicBlock {
      *
      * @param rmeth original method
      * @param basicBlockIndex index this block will have
-     * @param parent method of this block
-     * predecessor set will be updated.
+     * @param parent method of this block predecessor set will be
+     * updated
      * @return new instance
      */
     public static SsaBasicBlock newFromRop(RopMethod rmeth,
@@ -178,7 +178,7 @@ public final class SsaBasicBlock {
      *
      * @param child {@code non-null;} new dom child
      */
-    void addDomChild(SsaBasicBlock child) {
+    public void addDomChild(SsaBasicBlock child) {
         domChildren.add(child);
     }
 
@@ -187,7 +187,7 @@ public final class SsaBasicBlock {
      *
      * @return {@code non-null;} list of dom children
      */
-    ArrayList<SsaBasicBlock> getDomChildren() {
+    public ArrayList<SsaBasicBlock> getDomChildren() {
         return domChildren;
     }
 
@@ -197,7 +197,7 @@ public final class SsaBasicBlock {
      *
      * @param reg {@code >=0;} result reg
      */
-    void addPhiInsnForReg(int reg) {
+    public void addPhiInsnForReg(int reg) {
         insns.add(0, new PhiInsn(reg, this));
     }
 
@@ -208,7 +208,7 @@ public final class SsaBasicBlock {
      *
      * @param resultSpec {@code non-null;} reg
      */
-    void addPhiInsnForReg(RegisterSpec resultSpec) {
+    public void addPhiInsnForReg(RegisterSpec resultSpec) {
         insns.add(0, new PhiInsn(resultSpec, this));
     }
 
@@ -218,7 +218,7 @@ public final class SsaBasicBlock {
      *
      * @param insn {@code non-null;} rop-form insn to add
      */
-    void addInsnToHead(Insn insn) {
+    public void addInsnToHead(Insn insn) {
         SsaInsn newInsn = SsaInsn.makeFromRop(insn, this);
         insns.add(getCountPhiInsns(), newInsn);
         parent.onInsnAdded(newInsn);
@@ -230,7 +230,7 @@ public final class SsaBasicBlock {
      *
      * @param insn {@code non-null;} rop-form insn to add, which must branch.
      */
-    void replaceLastInsn(Insn insn) {
+    public void replaceLastInsn(Insn insn) {
         if (insn.getOpcode().getBranchingness() == Rop.BRANCH_NONE) {
             throw new IllegalArgumentException("last insn must branch");
         }
@@ -246,12 +246,12 @@ public final class SsaBasicBlock {
 
     /**
      * Visits each phi insn.
-     * 
+     *
      * @param v {@code non-null;} the callback
      */
     public void forEachPhiInsn(PhiInsn.Visitor v) {
-
         int sz = insns.size();
+
         for (int i = 0; i < sz; i++) {
             SsaInsn insn = insns.get(i);
             if (insn instanceof PhiInsn) {
@@ -272,7 +272,7 @@ public final class SsaBasicBlock {
     public void removeAllPhiInsns() {
         /*
          * Presently we assume PhiInsn's are in a continuous
-         * block at the top of the list
+         * block at the top of the list.
          */
 
         insns.subList(0, getCountPhiInsns()).clear();
@@ -280,6 +280,7 @@ public final class SsaBasicBlock {
 
     /**
      * Gets the number of phi insns at the top of this basic block.
+     *
      * @return count of phi insns
      */
     private int getCountPhiInsns() {
@@ -298,7 +299,7 @@ public final class SsaBasicBlock {
 
     /**
      * @return {@code non-null;} the (mutable) instruction list for this block,
-     * with phi insns at the beginning.
+     * with phi insns at the beginning
      */
     public ArrayList<SsaInsn> getInsns() {
         return insns;
@@ -356,7 +357,7 @@ public final class SsaBasicBlock {
 
     /**
      * @return {@code >= -1;} block index of primary successor or
-     * {@code -1} if no primary successor.
+     * {@code -1} if no primary successor
      */
     public int getPrimarySuccessorIndex() {
         return primarySuccessor;
@@ -411,18 +412,18 @@ public final class SsaBasicBlock {
     public SsaBasicBlock insertNewPredecessor() {
         SsaBasicBlock newPred = parent.makeNewGotoBlock();
 
-        // Update the new block
+        // Update the new block.
         newPred.predecessors = predecessors;
         newPred.successors.set(index) ;
         newPred.successorList.add(index);
         newPred.primarySuccessor = index;
 
 
-        // Update us
+        // Update us.
         predecessors = new BitSet(parent.getBlocks().size());
         predecessors.set(newPred.index);
 
-        // Update our (soon-to-be) old predecessors
+        // Update our (soon-to-be) old predecessors.
         for (int i = newPred.predecessors.nextSetBit(0); i >= 0;
                 i = newPred.predecessors.nextSetBit(i + 1)) {
 
@@ -453,13 +454,13 @@ public final class SsaBasicBlock {
                     + " not successor of " + getRopLabelString());
         }
 
-        // Update the new block
+        // Update the new block.
         newSucc.predecessors.set(this.index);
         newSucc.successors.set(other.index) ;
         newSucc.successorList.add(other.index);
         newSucc.primarySuccessor = other.index;
 
-        // Update us
+        // Update us.
         for (int i = successorList.size() - 1 ;  i >= 0; i--) {
             if (successorList.get(i) == other.index) {
                 successorList.set(i, newSucc.index);
@@ -472,7 +473,7 @@ public final class SsaBasicBlock {
         successors.clear(other.index);
         successors.set(newSucc.index);
 
-        // Update "other"
+        // Update "other".
         other.predecessors.set(newSucc.index);
         other.predecessors.set(index, successors.get(other.index));
 
@@ -482,9 +483,9 @@ public final class SsaBasicBlock {
     /**
      * Replaces an old successor with a new successor. This will throw
      * RuntimeException if {@code oldIndex} was not a successor.
-     * 
+     *
      * @param oldIndex index of old successor block
-     * @param newIndex index of new successor block.
+     * @param newIndex index of new successor block
      */
     public void replaceSuccessor(int oldIndex, int newIndex) {
         if (oldIndex == newIndex) {
@@ -543,7 +544,7 @@ public final class SsaBasicBlock {
      * before the last instruction. If the result of the final instruction
      * is the source in question, then the move is placed at the beginning of
      * the primary successor block. This is for unversioned registers.
-     * 
+     *
      * @param result move destination
      * @param source move source
      */
@@ -563,12 +564,13 @@ public final class SsaBasicBlock {
 
         if (lastInsn.getResult() != null || lastInsn.getSources().size() > 0) {
             /*
-             * The final insn in this block has a source or result register,
-             * and the moves we may need to place and schedule may interfere.
-             * We need to insert this instruction at the
-             * beginning of the primary successor block instead. We know
-             * this is safe, because when we edge-split earlier, we ensured
-             * that each successor has only us as a predecessor.
+             * The final insn in this block has a source or result
+             * register, and the moves we may need to place and
+             * schedule may interfere. We need to insert this
+             * instruction at the beginning of the primary successor
+             * block instead. We know this is safe, because when we
+             * edge-split earlier, we ensured that each successor has
+             * only us as a predecessor.
              */
 
             for (int i = successors.nextSetBit(0)
@@ -582,17 +584,12 @@ public final class SsaBasicBlock {
             }
         } else {
             /*
-             * We can safely add a move to the end of the block
-             * just before the last instruction because
-             * the final insn does not assign to anything.
+             * We can safely add a move to the end of the block just
+             * before the last instruction, because the final insn does
+             * not assign to anything.
              */
-
-            RegisterSpecList sources;
-            sources = RegisterSpecList.make(source);
-
-            NormalSsaInsn toAdd;
-
-            toAdd = new NormalSsaInsn(
+            RegisterSpecList sources = RegisterSpecList.make(source);
+            NormalSsaInsn toAdd = new NormalSsaInsn(
                     new PlainInsn(Rops.opMove(result.getType()),
                             SourcePosition.NO_INFO, result, sources), this);
 
@@ -604,7 +601,7 @@ public final class SsaBasicBlock {
 
     /**
      * Adds a move instruction after the phi insn block.
-     * 
+     *
      * @param result move destination
      * @param source move source
      */
@@ -614,17 +611,13 @@ public final class SsaBasicBlock {
             return;
         }
 
-        RegisterSpecList sources;
-        sources = RegisterSpecList.make(source);
-
-        NormalSsaInsn toAdd;
-
-        toAdd = new NormalSsaInsn(
-                    new PlainInsn(Rops.opMove(result.getType()),
-                            SourcePosition.NO_INFO, result, sources), this);
+        RegisterSpecList sources = RegisterSpecList.make(source);
+        NormalSsaInsn toAdd = new NormalSsaInsn(
+                new PlainInsn(Rops.opMove(result.getType()),
+                        SourcePosition.NO_INFO, result, sources), this);
 
         insns.add(getCountPhiInsns(), toAdd);
-        movesFromPhisAtBeginning++;        
+        movesFromPhisAtBeginning++;
     }
 
     /**
@@ -637,7 +630,7 @@ public final class SsaBasicBlock {
     private static void setRegsUsed (BitSet regsUsed, RegisterSpec rs) {
         regsUsed.set(rs.getReg());
         if (rs.getCategory() > 1) {
-            regsUsed.set(rs.getReg() + 1);            
+            regsUsed.set(rs.getReg() + 1);
         }
     }
 
@@ -666,12 +659,13 @@ public final class SsaBasicBlock {
      * TODO: See Briggs, et al "Practical Improvements to the Construction and
      * Destruction of Static Single Assignment Form" section 5. a) This can
      * be done in three passes.
-     * 
+     *
      * @param toSchedule List of instructions. Must consist only of moves.
      */
     private void scheduleUseBeforeAssigned(List<SsaInsn> toSchedule) {
         BitSet regsUsedAsSources = new BitSet(parent.getRegCount());
-        // TODO get rid of this
+
+        // TODO: Get rid of this.
         BitSet regsUsedAsResults = new BitSet(parent.getRegCount());
 
         int sz = toSchedule.size();
@@ -706,8 +700,10 @@ public final class SsaBasicBlock {
                 }
             }
 
-            // If we've made no progress in this iteration, there's a
-            // circular dependency.  Split it using the temp reg.
+            /*
+             * If we've made no progress in this iteration, there's a
+             * circular dependency. Split it using the temp reg.
+             */
             if (oldInsertPlace == insertPlace) {
 
                 SsaInsn insnToSplit = null;
@@ -720,43 +716,40 @@ public final class SsaBasicBlock {
                                 insn.getSources().get(0))) {
 
                         insnToSplit = insn;
-                        // We're going to split this insn--move it to the
-                        // front
+                        /*
+                         * We're going to split this insn; move it to the
+                         * front.
+                         */
                         Collections.swap(toSchedule, insertPlace, i);
                         break;
                     }
                 }
 
-                // At least one insn will be set above
+                // At least one insn will be set above.
 
                 RegisterSpec result = insnToSplit.getResult();
                 RegisterSpec tempSpec = result.withReg(
                         parent.borrowSpareRegister(result.getCategory()));
 
-                NormalSsaInsn toAdd;
-
-                toAdd = new NormalSsaInsn(
-                            new PlainInsn(Rops.opMove(result.getType()),
-                                    SourcePosition.NO_INFO,
-                                    tempSpec,
-                                    insnToSplit.getSources()), this);
+                NormalSsaInsn toAdd = new NormalSsaInsn(
+                        new PlainInsn(Rops.opMove(result.getType()),
+                                SourcePosition.NO_INFO,
+                                tempSpec,
+                                insnToSplit.getSources()), this);
 
                 toSchedule.add(insertPlace++, toAdd);
 
-                NormalSsaInsn toReplace;
-                RegisterSpecList newSources;
-
-                newSources = RegisterSpecList.make(tempSpec);
+                RegisterSpecList newSources = RegisterSpecList.make(tempSpec);
 
-                toReplace = new NormalSsaInsn(
-                            new PlainInsn(Rops.opMove(result.getType()),
-                                    SourcePosition.NO_INFO,
-                                    result,
-                                    newSources), this);
+                NormalSsaInsn toReplace = new NormalSsaInsn(
+                        new PlainInsn(Rops.opMove(result.getType()),
+                                SourcePosition.NO_INFO,
+                                result,
+                                newSources), this);
 
                 toSchedule.set(insertPlace, toReplace);
 
-                // size has changed
+                // The size changed.
                 sz = toSchedule.size();
             }
 
@@ -768,7 +761,7 @@ public final class SsaBasicBlock {
     /**
      * Adds {@code regV} to the live-out list for this block. This is called
      * by the liveness analyzer.
-     * 
+     *
      * @param regV register that is live-out for this block.
      */
     public void addLiveOut (int regV) {
@@ -782,7 +775,7 @@ public final class SsaBasicBlock {
     /**
      * Adds {@code regV} to the live-in list for this block. This is
      * called by the liveness analyzer.
-     * 
+     *
      * @param regV register that is live-in for this block.
      */
     public void addLiveIn (int regV) {
@@ -790,7 +783,7 @@ public final class SsaBasicBlock {
             liveIn = SetFactory.makeLivenessSet(parent.getRegCount());
         }
 
-        liveIn.add(regV);       
+        liveIn.add(regV);
     }
 
     /**
@@ -809,8 +802,8 @@ public final class SsaBasicBlock {
     /**
      * Returns the set of live-out registers. Valid after register
      * interference graph has been generated, otherwise empty.
-     * 
-     * @return {@code non-null;} live-out register set.
+     *
+     * @return {@code non-null;} live-out register set
      */
     public IntSet getLiveOutRegs() {
         if (liveOut == null) {
@@ -832,13 +825,13 @@ public final class SsaBasicBlock {
      * that it's either the start block or it has predecessors, which suffices
      * for all current control flow transformations.
      *
-     * @return true if reachable
+     * @return {@code true} if reachable
      */
     public boolean isReachable() {
         return index == parent.getEntryBlockIndex()
                 || predecessors.cardinality() > 0;
     }
-        
+
     /**
      * Sorts move instructions added via {@code addMoveToEnd} during
      * phi removal so that results don't overwrite sources that are used.
@@ -860,31 +853,36 @@ public final class SsaBasicBlock {
 
             SsaInsn firstNonPhiMoveInsn = insns.get(movesFromPhisAtBeginning);
 
-            //TODO it's actually possible that this case never happens,
-            //because a move-exception block, having only one predecessor
-            //in SSA form, perhaps is never on a dominance frontier.
+            /*
+             * TODO: It's actually possible that this case never happens,
+             * because a move-exception block, having only one predecessor
+             * in SSA form, perhaps is never on a dominance frontier.
+             */
             if (firstNonPhiMoveInsn.isMoveException()) {
                 if (true) {
                     /*
                      * We've yet to observe this case, and if it can
-                     * occur the code written to handle it probably 
+                     * occur the code written to handle it probably
                      * does not work.
                      */
                     throw new RuntimeException(
                             "Unexpected: moves from "
                                     +"phis before move-exception");
                 } else {
-
-                    // A move-exception insn must be placed first in this block
-                    // We need to move it there, and deal with possible
-                    // interference.
+                    /*
+                     * A move-exception insn must be placed first in this block
+                     * We need to move it there, and deal with possible
+                     * interference.
+                     */
                     boolean moveExceptionInterferes = false;
 
                     int moveExceptionResult
                             = firstNonPhiMoveInsn.getResult().getReg();
 
-                    // Does the move-exception result reg interfere with the
-                    // phi moves?
+                    /*
+                     * Does the move-exception result reg interfere with the
+                     * phi moves?
+                     */
                     for (SsaInsn insn : toSchedule) {
                         if (insn.isResultReg(moveExceptionResult)
                                 || insn.isRegASource(moveExceptionResult)) {
@@ -898,14 +896,13 @@ public final class SsaBasicBlock {
                         insns.remove(movesFromPhisAtBeginning);
                         insns.add(0, firstNonPhiMoveInsn);
                     } else {
-                        // We need to move the result to a spare reg
-                        // and move it back.
-
-                        int spareRegister;
-                        RegisterSpec originalResultSpec;
-
-                        originalResultSpec = firstNonPhiMoveInsn.getResult();
-                        spareRegister = parent.borrowSpareRegister(
+                        /*
+                         * We need to move the result to a spare reg
+                         * and move it back.
+                         */
+                        RegisterSpec originalResultSpec
+                            = firstNonPhiMoveInsn.getResult();
+                        int spareRegister = parent.borrowSpareRegister(
                                 originalResultSpec.getCategory());
 
                         // We now move it to a spare register.
@@ -915,26 +912,27 @@ public final class SsaBasicBlock {
 
                         insns.add(0, firstNonPhiMoveInsn);
 
-                        // And here we move it back
-
-                        NormalSsaInsn toAdd;
+                        // And here we move it back.
 
-                        toAdd = new NormalSsaInsn(
-                                    new PlainInsn(Rops.opMove(
-                                            tempSpec.getType()),
-                                            SourcePosition.NO_INFO,
-                                            originalResultSpec,
-                                            RegisterSpecList.make(tempSpec)),
+                        NormalSsaInsn toAdd = new NormalSsaInsn(
+                                new PlainInsn(
+                                        Rops.opMove(tempSpec.getType()),
+                                        SourcePosition.NO_INFO,
+                                        originalResultSpec,
+                                        RegisterSpecList.make(tempSpec)),
                                 this);
 
 
-                        // Place it immediately after the phi-moves,
-                        // overwriting the move-exception that was there.
+                        /*
+                         * Place it immediately after the phi-moves,
+                         * overwriting the move-exception that was there.
+                         */
                         insns.set(movesFromPhisAtBeginning + 1, toAdd);
                     }
                 }
             }
         }
+
         if (movesFromPhisAtEnd > 1) {
             scheduleUseBeforeAssigned(
                     insns.subList(insns.size() - movesFromPhisAtEnd - 1,
@@ -947,8 +945,8 @@ public final class SsaBasicBlock {
     }
 
     /**
-     * Visit all insns in this block.
-     * 
+     * Visits all insns in this block.
+     *
      * @param visitor {@code non-null;} callback interface
      */
     public void forEachInsn(SsaInsn.Visitor visitor) {
@@ -968,7 +966,7 @@ public final class SsaBasicBlock {
     public interface Visitor {
         /**
          * Indicates a block has been visited by an iterator method.
-         * 
+         *
          * @param v {@code non-null;} block visited
          * @param parent {@code null-ok;} parent node if applicable
          */
index 252b1d5..99aab3d 100644 (file)
@@ -30,19 +30,20 @@ public class SsaConverter {
     public static boolean DEBUG = false;
 
     /**
-     * returns an SSA representation, edge-split and with phi functions placed
+     * Returns an SSA representation, edge-split and with phi
+     * functions placed.
+     *
      * @param rmeth input
      * @param paramWidth the total width, in register-units, of the method's
      * parameters
-     * @param isStatic true if this method has no 'this'
+     * @param isStatic {@code true} if this method has no {@code this}
      * pointer argument
      * @return output in SSA form
      */
-    public static SsaMethod convertToSsaMethod(RopMethod rmeth, 
+    public static SsaMethod convertToSsaMethod(RopMethod rmeth,
             int paramWidth, boolean isStatic) {
-        SsaMethod result;
-
-        result = SsaMethod.newFromRopMethod(rmeth, paramWidth, isStatic);
+        SsaMethod result
+            = SsaMethod.newFromRopMethod(rmeth, paramWidth, isStatic);
 
         edgeSplit(result);
 
@@ -52,7 +53,7 @@ public class SsaConverter {
         new SsaRenamer(result).run();
 
         /*
-         * Exit block, added here,  is not considered for edge splitting
+         * The exit block, added here, is not considered for edge splitting
          * or phi placement since no actual control flows to it.
          */
         result.makeExitBlock();
@@ -62,10 +63,12 @@ public class SsaConverter {
 
     /**
      * Returns an SSA represention with only the edge-splitter run.
+     *
      * @param rmeth method to process
      * @param paramWidth width of all arguments in the method
-     * @param isStatic true if this method has no 'this' pointer argument
-     * @return an SSA represention with only the edge-splitter run.
+     * @param isStatic {@code true} if this method has no {@code this}
+     * pointer argument
+     * @return an SSA represention with only the edge-splitter run
      */
     public static SsaMethod testEdgeSplit (RopMethod rmeth, int paramWidth,
             boolean isStatic) {
@@ -80,10 +83,12 @@ public class SsaConverter {
     /**
      * Returns an SSA represention with only the steps through the
      * phi placement run.
+     *
      * @param rmeth method to process
      * @param paramWidth width of all arguments in the method
-     * @param isStatic true if this method has no 'this' pointer argument
-     * @return an SSA represention with only the edge-splitter run.
+     * @param isStatic {@code true} if this method has no {@code this}
+     * pointer argument
+     * @return an SSA represention with only the edge-splitter run
      */
     public static SsaMethod testPhiPlacement (RopMethod rmeth, int paramWidth,
             boolean isStatic) {
@@ -100,7 +105,8 @@ public class SsaConverter {
     }
 
     /**
-     * See Appel section 19.1
+     * See Appel section 19.1:
+     *
      * Converts CFG into "edge-split" form, such that each node either a
      * unique successor or unique predecessor.<p>
      *
@@ -109,11 +115,10 @@ public class SsaConverter {
      * value to have a primary successor that has no other
      * predecessor. This ensures move statements can always be
      * inserted correctly when phi statements are removed.
-     * 
+     *
      * @param result method to process
      */
     private static void edgeSplit(SsaMethod result) {
-
         edgeSplitPredecessors(result);
         edgeSplitMoveExceptionsAndResults(result);
         edgeSplitSuccessors(result);
@@ -122,13 +127,16 @@ public class SsaConverter {
     /**
      * Inserts Z nodes as new predecessors for every node that has multiple
      * successors and multiple predecessors.
+     *
      * @param result {@code non-null;} method to process
      */
     private static void edgeSplitPredecessors(SsaMethod result) {
         ArrayList<SsaBasicBlock> blocks = result.getBlocks();
-        
-        // New blocks are added to the end of the block list during
-        // this iteration
+
+        /*
+         * New blocks are added to the end of the block list during
+         * this iteration.
+         */
         for (int i = blocks.size() - 1; i >= 0; i-- ) {
             SsaBasicBlock block = blocks.get(i);
             if (nodeNeedsUniquePredecessor(block)) {
@@ -139,11 +147,10 @@ public class SsaConverter {
 
     /**
      * @param block {@code non-null;} block in question
-     * @return true if this node needs to have a unique predecessor created for
-     * it.
+     * @return {@code true} if this node needs to have a unique
+     * predecessor created for it
      */
     private static boolean nodeNeedsUniquePredecessor(SsaBasicBlock block) {
-
         /*
          * Any block with that has both multiple successors and multiple
          * predecessors needs a new predecessor node.
@@ -161,56 +168,65 @@ public class SsaConverter {
      * We may need room to insert move insns later, so make sure to split
      * any block that starts with a move-exception such that there is a
      * unique move-exception block for each predecessor.
+     *
      * @param ssaMeth method to process
      */
     private static void edgeSplitMoveExceptionsAndResults(SsaMethod ssaMeth) {
         ArrayList<SsaBasicBlock> blocks = ssaMeth.getBlocks();
 
-        // New blocks are added to the end of the block list during
-        // this iteration
+        /*
+         * New blocks are added to the end of the block list during
+         * this iteration.
+         */
         for (int i = blocks.size() - 1; i >= 0; i-- ) {
             SsaBasicBlock block = blocks.get(i);
-        
-            // Any block that starts with a move-exception and has more than
-            // one predecessor...
+
+            /*
+             * Any block that starts with a move-exception and has more than
+             * one predecessor...
+             */
             if (!block.isExitBlock()
-                    && block.getPredecessors().cardinality() > 1 
+                    && block.getPredecessors().cardinality() > 1
                     && block.getInsns().get(0).isMoveException()) {
 
-                // block.getPredecessors() is changed in the loop below
+                // block.getPredecessors() is changed in the loop below.
                 BitSet preds = (BitSet)block.getPredecessors().clone();
                 for (int j = preds.nextSetBit(0); j >= 0;
-                        j = preds.nextSetBit(j + 1)) {
-
+                     j = preds.nextSetBit(j + 1)) {
                     SsaBasicBlock predecessor = blocks.get(j);
+                    SsaBasicBlock zNode
+                        = predecessor.insertNewSuccessor(block);
 
-                    SsaBasicBlock zNode = predecessor.insertNewSuccessor(block);
-
-                    // Make sure to place the move-exception as the
-                    // first insn...
+                    /*
+                     * Make sure to place the move-exception as the
+                     * first insn.
+                     */
                     zNode.getInsns().add(0, block.getInsns().get(0).clone());
                 }
 
-                // remove the move-exception from the original block...
+                // Remove the move-exception from the original block.
                 block.getInsns().remove(0);
             }
         }
     }
 
     /**
-     * Inserts Z nodes for every node that needs a new 
+     * Inserts Z nodes for every node that needs a new
      * successor.
+     *
      * @param result {@code non-null;} method to process
      */
     private static void edgeSplitSuccessors(SsaMethod result) {
         ArrayList<SsaBasicBlock> blocks = result.getBlocks();
 
-        // New blocks are added to the end of the block list during
-        // this iteration
+        /*
+         * New blocks are added to the end of the block list during
+         * this iteration.
+         */
         for (int i = blocks.size() - 1; i >= 0; i-- ) {
             SsaBasicBlock block = blocks.get(i);
 
-            // successors list is modified in loop below
+            // Successors list is modified in loop below.
             BitSet successors = (BitSet)block.getSuccessors().clone();
             for (int j = successors.nextSetBit(0);
                  j >= 0; j = successors.nextSetBit(j+1)) {
@@ -225,17 +241,17 @@ public class SsaConverter {
     }
 
     /**
-     * Returns true if block and successor need a Z-node between them.
-     * Presently, this is true if the final instruction has any sources
-     * or results and the current successor block has more than one
-     * predecessor.
+     * Returns {@code true} if block and successor need a Z-node
+     * between them. Presently, this is {@code true} if the final
+     * instruction has any sources or results and the current
+     * successor block has more than one predecessor.
+     *
      * @param block predecessor node
      * @param succ successor node
-     * @return true if a Z node is needed
+     * @return {@code true} if a Z node is needed
      */
     private static boolean needsNewSuccessor(SsaBasicBlock block,
             SsaBasicBlock succ) {
-
         ArrayList<SsaInsn> insns = block.getInsns();
         SsaInsn lastInsn = insns.get(insns.size() - 1);
 
@@ -245,11 +261,14 @@ public class SsaConverter {
     }
 
     /**
-     * See Appel algorithm 19.6
+     * See Appel algorithm 19.6:
+     *
      * Place Phi functions in appropriate locations.
      *
-     * @param ssaMeth {@code non-null;} method to process. Modifications made in-place
-     * @param localInfo {@code non-null;} Local variable info, used when placing phis
+     * @param ssaMeth {@code non-null;} method to process.
+     * Modifications are made in-place.
+     * @param localInfo {@code non-null;} local variable info, used
+     * when placing phis
      */
     private static void placePhiFunctions (SsaMethod ssaMeth,
             LocalVariableInfo localInfo) {
@@ -296,11 +315,8 @@ public class SsaConverter {
 
             for (int i = 0; i < regCount; i++) {
                 StringBuilder sb = new StringBuilder();
-
                 sb.append('v').append(i).append(": ");
-
                 sb.append(defsites[i].toString());
-
                 System.out.println(sb);
             }
         }
@@ -314,15 +330,14 @@ public class SsaConverter {
         for (int reg = 0, s = ssaMeth.getRegCount() ; reg < s ; reg++ ) {
             int workBlockIndex;
 
-            /* Worklist set starts out with each node where reg is assigned */
+            /* Worklist set starts out with each node where reg is assigned. */
 
-            worklist = (BitSet)(defsites[reg].clone());
+            worklist = (BitSet) (defsites[reg].clone());
 
             while (0 <= (workBlockIndex = worklist.nextSetBit(0))) {
                 worklist.clear(workBlockIndex);
                 IntIterator dfIterator
-                        = domInfos[workBlockIndex]
-                        .dominanceFrontiers.iterator();
+                    = domInfos[workBlockIndex].dominanceFrontiers.iterator();
 
                 while (dfIterator.hasNext()) {
                     int dfBlockIndex = dfIterator.next();
@@ -352,11 +367,8 @@ public class SsaConverter {
 
             for (int i = 0; i < regCount; i++) {
                 StringBuilder sb = new StringBuilder();
-
                 sb.append('v').append(i).append(": ");
-
                 sb.append(phisites[i].toString());
-
                 System.out.println(sb);
             }
         }
index 10859f5..ad7ef03 100644 (file)
@@ -54,11 +54,11 @@ import java.util.HashMap;
  * current block has been processed, this mapping table is then copied
  * and used as the initial state for child blocks.<p>
  */
-class SsaRenamer implements Runnable {
-
+public class SsaRenamer implements Runnable {
+    /** debug flag */
     private static final boolean DEBUG = false;
 
-    /** Method we're processing */
+    /** method we're processing */
     private final SsaMethod ssaMeth;
 
     /** next available SSA register */
@@ -68,7 +68,7 @@ class SsaRenamer implements Runnable {
     private final int ropRegCount;
 
     /**
-     * Indexed by block index; register version state for each block start.
+     * indexed by block index; register version state for each block start.
      * This list is updated by each dom parent for its children. The only
      * sub-arrays that exist at any one time are the start states for blocks
      * yet to be processed by a {@code BlockRenamer} instance.
@@ -79,8 +79,8 @@ class SsaRenamer implements Runnable {
     private final ArrayList<LocalItem> ssaRegToLocalItems;
 
     /**
-     * Maps SSA registers back to the original rop number.
-     * Used for debug only.
+     * maps SSA registers back to the original rop number. Used for
+     * debug only.
      */
     private IntList ssaRegToRopReg;
 
@@ -90,13 +90,14 @@ class SsaRenamer implements Runnable {
      * @param ssaMeth {@code non-null;} un-renamed SSA method that will
      * be renamed.
      */
-    SsaRenamer (final SsaMethod ssaMeth) {
+    public SsaRenamer(SsaMethod ssaMeth) {
         ropRegCount = ssaMeth.getRegCount();
 
         this.ssaMeth = ssaMeth;
+
         /*
          * Reserve the first N registers in the SSA register space for
-         * "version 0" registers
+         * "version 0" registers.
          */
         nextSsaReg = ropRegCount;
         startsForBlocks = new RegisterSpec[ssaMeth.getBlocks().size()][];
@@ -138,7 +139,6 @@ class SsaRenamer implements Runnable {
      * in-place.
      */
     public void run() {
-
         // Rename each block in dom-tree DFS order.
         ssaMeth.forEachBlockDepthFirstDom(new SsaBasicBlock.Visitor() {
             public void visitBlock (SsaBasicBlock block,
@@ -152,9 +152,11 @@ class SsaRenamer implements Runnable {
 
         if (DEBUG) {
             System.out.println("SSA\tRop");
-            // We're going to compute the version of the rop register
-            // by keeping a running total of how many times the rop register
-            // has been mapped.
+            /*
+             * We're going to compute the version of the rop register
+             * by keeping a running total of how many times the rop
+             * register has been mapped.
+             */
             int[] versions = new int[ropRegCount];
 
             int sz = ssaRegToRopReg.size();
@@ -168,7 +170,8 @@ class SsaRenamer implements Runnable {
     }
 
     /**
-     * Duplicates a RegisterSpec array
+     * Duplicates a RegisterSpec array.
+     *
      * @param orig {@code non-null;} array to duplicate
      * @return {@code non-null;} new instance
      */
@@ -224,8 +227,8 @@ class SsaRenamer implements Runnable {
     }
 
     /**
-     * Returns true if a and b are equal or are both null
-
+     * Returns true if a and b are equal or are both null.
+     *
      * @param a null-ok
      * @param b null-ok
      * @return Returns true if a and b are equal or are both null
@@ -243,22 +246,22 @@ class SsaRenamer implements Runnable {
         private final SsaBasicBlock block;
 
         /**
-         * {@code non-null;} indexed by old register name. The current top of the
-         * version stack as seen by this block. It's initialized from
-         * the ending state of its dom parent, updated as the block's
-         * instructions are processed, and then copied to each one of its
-         * dom children.
+         * {@code non-null;} indexed by old register name. The current
+         * top of the version stack as seen by this block. It's
+         * initialized from the ending state of its dom parent,
+         * updated as the block's instructions are processed, and then
+         * copied to each one of its dom children.
          */
         private final RegisterSpec[] currentMapping;
 
         /**
-         * Contains the set of moves we need to keep
-         * to preserve local var info. All other moves will be deleted.
+         * contains the set of moves we need to keep to preserve local
+         * var info. All other moves will be deleted.
          */
         private final HashSet<SsaInsn> movesToKeep;
 
         /**
-         * Maps the set of insns to replace after renaming is finished
+         * maps the set of insns to replace after renaming is finished
          * on the block.
          */
         private final HashMap<SsaInsn, SsaInsn> insnsToReplace;
@@ -288,8 +291,8 @@ class SsaRenamer implements Runnable {
          * as the current block's instructions are processed.
          */
         private class RenamingMapper extends RegisterMapper {
-
-            RenamingMapper() {
+            public RenamingMapper() {
+                // This space intentionally left blank.
             }
 
             /** {@inheritDoc} */
@@ -305,7 +308,7 @@ class SsaRenamer implements Runnable {
 
                 int reg = registerSpec.getReg();
 
-                // for debugging: assert that the mapped types are compatible
+                // For debugging: assert that the mapped types are compatible.
                 if (DEBUG) {
                     RegisterSpec newVersion = currentMapping[reg];
                     if (newVersion.getBasicType() != Type.BT_VOID
@@ -339,7 +342,7 @@ class SsaRenamer implements Runnable {
 
             updateSuccessorPhis();
 
-            // Delete all move insns in this block
+            // Delete all move insns in this block.
             ArrayList<SsaInsn> insns = block.getInsns();
             int szInsns = insns.size();
 
@@ -350,29 +353,27 @@ class SsaRenamer implements Runnable {
                 replaceInsn = insnsToReplace.get(insn);
 
                 if (replaceInsn != null) {
-                    insns.set(i, replaceInsn);                    
+                    insns.set(i, replaceInsn);
                 } else if (insn.isNormalMoveInsn()
                         && !movesToKeep.contains(insn)) {
                     insns.remove(i);
                 }
             }
 
-            // Store the start states for our dom children
+            // Store the start states for our dom children.
             boolean first = true;
             for (SsaBasicBlock child : block.getDomChildren()) {
                 if (child != block) {
-                    RegisterSpec[] childStart;
-
-                    // don't bother duplicating the array for the first child
-                    childStart = first ? currentMapping
-                            : dupArray(currentMapping);
+                    // Don't bother duplicating the array for the first child.
+                    RegisterSpec[] childStart = first ? currentMapping
+                        : dupArray(currentMapping);
 
                     startsForBlocks[child.getIndex()] = childStart;
                     first = false;
                 }
             }
 
-            // currentMapping is owned by a child now
+            // currentMapping is owned by a child now.
         }
 
         /**
@@ -414,15 +415,15 @@ class SsaRenamer implements Runnable {
                 }
             }
 
-            // All further steps are for registers with local information
+            // All further steps are for registers with local information.
             if (ssaRegLocal == null) {
                 return;
             }
 
-            // Record that this SSA reg has been associated with a local
+            // Record that this SSA reg has been associated with a local.
             setNameForSsaReg(ssaReg);
 
-            // Ensure that no other SSA regs are associated with this local
+            // Ensure that no other SSA regs are associated with this local.
             for (int i = currentMapping.length - 1; i >= 0; i--) {
                 RegisterSpec cur = currentMapping[i];
 
@@ -437,7 +438,7 @@ class SsaRenamer implements Runnable {
          * {@inheritDoc}
          *
          * Phi insns have their result registers renamed.
-         * */
+         */
         public void visitPhiInsn(PhiInsn phi) {
             /* don't process sources for phi's */
             processResultReg(phi);
@@ -453,7 +454,7 @@ class SsaRenamer implements Runnable {
          */
         public void visitMoveInsn(NormalSsaInsn insn) {
             /*
-             * for moves: copy propogate the move if we can, but don't
+             * For moves: copy propogate the move if we can, but don't
              * if we need to preserve local variable info and the
              * result has a different name than the source.
              */
@@ -465,7 +466,8 @@ class SsaRenamer implements Runnable {
             insn.mapSourceRegisters(mapper);
             int ssaSourceReg = insn.getSources().get(0).getReg();
 
-            LocalItem sourceLocal = currentMapping[ropSourceReg].getLocalItem();
+            LocalItem sourceLocal
+                = currentMapping[ropSourceReg].getLocalItem();
             LocalItem resultLocal = ropResult.getLocalItem();
 
             /*
@@ -476,25 +478,26 @@ class SsaRenamer implements Runnable {
              */
 
             LocalItem newLocal
-                    = (resultLocal == null) ? sourceLocal : resultLocal;
-
+                = (resultLocal == null) ? sourceLocal : resultLocal;
             LocalItem associatedLocal = getLocalForNewReg(ssaSourceReg);
 
-            // If we take the new local, will only one local have ever
-            // been associated with this SSA reg?
+            /*
+             * If we take the new local, will only one local have ever
+             * been associated with this SSA reg?
+             */
             boolean onlyOneAssociatedLocal
                     = associatedLocal == null || newLocal == null
                     || newLocal.equals(associatedLocal);
-                    
+
             /*
-             * If we're going to copy-propogate, then the ssa register spec
-             * that's going to go into the mapping is made up of the
-             * source register number mapped from above, the type
+             * If we're going to copy-propogate, then the ssa register
+             * spec that's going to go into the mapping is made up of
+             * the source register number mapped from above, the type
              * of the result, and the name either from the result (if
              * specified) or inherited from the existing mapping.
              *
-             * The move source has incomplete type information
-             * in null object cases, so the result type is used.
+             * The move source has incomplete type information in null
+             * object cases, so the result type is used.
              */
             RegisterSpec ssaReg
                     = RegisterSpec.makeLocalOptional(
@@ -510,15 +513,12 @@ class SsaRenamer implements Runnable {
 
                 addMapping(ropResultReg, ssaReg);
             } else if (onlyOneAssociatedLocal && sourceLocal == null) {
-
                 /*
                  * The register was previously unnamed. This means that a
                  * local starts after it's first assignment in SSA form
                  */
 
-                RegisterSpecList ssaSources;
-
-                ssaSources = RegisterSpecList.make(
+                RegisterSpecList ssaSources = RegisterSpecList.make(
                         RegisterSpec.make(ssaReg.getReg(),
                                 ssaReg.getType(), newLocal));
 
@@ -529,12 +529,12 @@ class SsaRenamer implements Runnable {
 
                 insnsToReplace.put(insn, newInsn);
 
-                // Just map as above
+                // Just map as above.
                 addMapping(ropResultReg, ssaReg);
             } else {
                 /*
-                 * Do not copy-propogate, since the two registers
-                 * have two different local-variable names
+                 * Do not copy-propogate, since the two registers have
+                 * two different local-variable names.
                  */
                 processResultReg(insn);
 
@@ -595,11 +595,12 @@ class SsaRenamer implements Runnable {
                     ropReg = insn.getRopResultReg();
 
                     /*
-                     * Never add a version 0 register as a phi operand.
-                     * Version 0 registers represent the initial register state,
-                     * and thus are never significant. Furthermore,
-                     * the register liveness algorithm doesn't properly
-                     * count them as "live in" at the beginning of the method.
+                     * Never add a version 0 register as a phi
+                     * operand. Version 0 registers represent the
+                     * initial register state, and thus are never
+                     * significant. Furthermore, the register liveness
+                     * algorithm doesn't properly count them as "live
+                     * in" at the beginning of the method.
                      */
 
                     RegisterSpec stackTop = currentMapping[ropReg];
index 43c2973..0cffcfa 100644 (file)
@@ -58,16 +58,16 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
     /** Register mapper which will be our result */
     private final InterferenceRegisterMapper mapper;
 
-    /** end of rop registers range (starting at 0) reserved for parameters. */
+    /** end of rop registers range (starting at 0) reserved for parameters */
     private final int paramRangeEnd;
 
-    /** set of Rop registers reserved for parameters or local variables. */
+    /** set of rop registers reserved for parameters or local variables */
     private final BitSet reservedRopRegs;
 
-    /** set of Rop registers that have been used by anything.*/
+    /** set of rop registers that have been used by anything */
     private final BitSet usedRopRegs;
 
-    /** true if converter should take steps to minimize rop-form registers*/
+    /** true if converter should take steps to minimize rop-form registers */
     private final boolean minimizeRegisters;
 
     /**
@@ -130,7 +130,7 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
 
         if (DEBUG) System.out.println("--->Mapping invoke-range");
         handleInvokeRangeInsns();
-        
+
         if (DEBUG) {
             System.out.println("--->Mapping local-associated non-params");
         }
@@ -167,7 +167,7 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
     }
 
     /**
-     * Maps all local-associated parameters to Rop registers.
+     * Maps all local-associated parameters to rop registers.
      */
     private void handleLocalAssociatedParams() {
         for (ArrayList<RegisterSpec> ssaRegs : localVariables.values()) {
@@ -175,7 +175,7 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
             int paramIndex = -1;
             int paramCategory = 0;
 
-            // First, find out if this local variable is a parameter
+            // First, find out if this local variable is a parameter.
             for (int i = 0; i < sz; i++) {
                 RegisterSpec ssaSpec = ssaRegs.get(i);
                 int ssaReg = ssaSpec.getReg();
@@ -190,31 +190,31 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
             }
 
             if (paramIndex < 0) {
-                // this local wasn't a parameter
+                // This local wasn't a parameter.
                 continue;
             }
 
-            // Any remaining local-associated registers will be mapped later
+            // Any remaining local-associated registers will be mapped later.
             tryMapRegs(ssaRegs, paramIndex, paramCategory, true);
         }
     }
 
     /**
      * Gets the parameter index for SSA registers that are method parameters.
-     * -1 is returned for non-parameter registers.
+     * {@code -1} is returned for non-parameter registers.
      *
      * @param ssaReg {@code >=0;} SSA register to look up
-     * @return parameter index or -1 if not a parameter
+     * @return parameter index or {@code -1} if not a parameter
      */
     private int getParameterIndexForReg(int ssaReg) {
         SsaInsn defInsn = ssaMeth.getDefinitionForRegister(ssaReg);
         if (defInsn == null) {
             return -1;
         }
-        
+
         Rop opcode = defInsn.getOpcode();
 
-        // opcode == null for phi insns
+        // opcode == null for phi insns.
         if (opcode != null && opcode.getOpcode() == RegOps.MOVE_PARAM) {
             CstInsn origInsn = (CstInsn) defInsn.getOriginalRopInsn();
             return  ((CstInteger) origInsn.getConstant()).getValue();
@@ -224,7 +224,7 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
     }
 
     /**
-     * Maps all local-associated registers that are not parameters. 
+     * Maps all local-associated registers that are not parameters.
      * Tries to find an unreserved range that's wide enough for all of
      * the SSA registers, and then tries to map them all to that
      * range. If not all fit, a new range is tried until all registers
@@ -238,7 +238,7 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
             do {
                 int maxCategory = 1;
 
-                // compute max category for remaining unmapped registers
+                // Compute max category for remaining unmapped registers.
                 int sz = specs.size();
                 for (int i = 0; i < sz; i++) {
                     RegisterSpec ssaSpec = specs.get(i);
@@ -253,7 +253,7 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
 
                 done = tryMapRegs(specs, ropReg, maxCategory, true);
 
-                // Increment for next call to findNext
+                // Increment for next call to findNext.
                 ropReg++;
             } while (!done);
         }
@@ -266,9 +266,11 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
      *
      * @param specs {@code non-null;} SSA registers to attempt to map
      * @param ropReg {@code >=0;} rop register to map to
-     * @param maxAllowedCategory 1 or 2, maximum category allowed in mapping.
-     * @param markReserved do so if true
-     * @return true if all registers wew mapped, false if some remain unmapped.
+     * @param maxAllowedCategory {@code 1..2;} maximum category
+     * allowed in mapping.
+     * @param markReserved do so if {@code true}
+     * @return {@code true} if all registers were mapped, {@code false}
+     * if some remain unmapped
      */
     private boolean tryMapRegs(
             ArrayList<RegisterSpec> specs, int ropReg,
@@ -296,9 +298,9 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
      *
      * @param ssaSpec {@code non-null;} SSA register
      * @param ropReg {@code >=0;} rop register
-     * @param maxAllowedCategory 1 or 2, the maximum category that the SSA
-     * register is allowed to be.
-     * @return true if map succeeded, false if not.
+     * @param maxAllowedCategory {@code 1..2;} the maximum category
+     * that the SSA register is allowed to be
+     * @return {@code true} if map succeeded, {@code false} if not
      */
     private boolean tryMapReg(RegisterSpec ssaSpec, int ropReg,
             int maxAllowedCategory) {
@@ -313,7 +315,7 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
     }
 
     /**
-     * Marks a range of Rop registers as "reserved for a local variable"
+     * Marks a range of rop registers as "reserved for a local variable."
      *
      * @param ropReg {@code >= 0;} rop register to reserve
      * @param category {@code > 0;} width to reserve
@@ -323,12 +325,12 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
     }
 
     /**
-     * Checks to see if any Rop registers in the specified range are reserved
-     * for local variables or parameters
+     * Checks to see if any rop registers in the specified range are reserved
+     * for local variables or parameters.
      *
-     * @param ropRangeStart {@code >= 0;} lowest Rop register
-     * @param width {@code > 0;} number of Rop registers in range.
-     * @return true if any register in range is marked reserved
+     * @param ropRangeStart {@code >= 0;} lowest rop register
+     * @param width {@code > 0;} number of rop registers in range.
+     * @return {@code true} if any register in range is marked reserved
      */
     private boolean rangeContainsReserved(int ropRangeStart, int width) {
         for (int i = ropRangeStart; i < (ropRangeStart + width); i++) {
@@ -340,21 +342,21 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
     }
 
     /**
-     * Returns true if given rop register represents the "this" pointer
-     * for a non-static method
+     * Returns true if given rop register represents the {@code this} pointer
+     * for a non-static method.
      *
      * @param startReg rop register
      * @return true if the "this" pointer is located here.
      */
     private boolean isThisPointerReg(int startReg) {
-        // "this" is always the first parameter
+        // "this" is always the first parameter.
         return startReg == 0 && !ssaMeth.isStatic();
     }
 
     /**
-     * Finds a range of unreserved Rop registers.
+     * Finds a range of unreserved rop registers.
      *
-     * @param startReg {@code >= 0;} a Rop register to start the search at
+     * @param startReg {@code >= 0;} a rop register to start the search at
      * @param width {@code > 0;} the width, in registers, required.
      * @return {@code >= 0;} start of available register range.
      */
@@ -384,10 +386,10 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
 
     /**
      * Finds a range of rop regs that can be used for local variables.
-     * If {@code MIX_LOCALS_AND_OTHER} is false, this means any
+     * If {@code MIX_LOCALS_AND_OTHER} is {@code false}, this means any
      * rop register that has not yet been used.
      *
-     * @param startReg {@code >= 0;} a Rop register to start the search at
+     * @param startReg {@code >= 0;} a rop register to start the search at
      * @param width {@code > 0;} the width, in registers, required.
      * @return {@code >= 0;} start of available register range.
      */
@@ -433,7 +435,7 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
             RegisterSpec ssaSpec = getDefinitionSpecForSsaReg(ssaReg);
             if (paramIndex >= 0) {
                 addMapping(ssaSpec, paramIndex);
-            }            
+            }
         }
     }
 
@@ -447,7 +449,8 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
     }
 
     /**
-     * Handles check cast results to reuse the same source register if possible
+     * Handles check cast results to reuse the same source register if
+     * possible.
      */
     private void handleCheckCastResults() {
         for (NormalSsaInsn insn : moveResultPseudoInsns) {
@@ -502,8 +505,7 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
     }
 
     /**
-     * Maps all non-parameter, non-local variable
-     * registers.
+     * Maps all non-parameter, non-local variable registers.
      */
     private void handleNormalUnassociated() {
         int szSsaRegs = ssaMeth.getRegCount();
@@ -536,24 +538,24 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
      *
      * @param ssaSpec {@code non-null;} SSA spec
      * @param ropReg prosepctive new-namespace reg
-     * @return true if mapping is possible
+     * @return {@code true} if mapping is possible
      */
     private boolean canMapReg(RegisterSpec ssaSpec, int ropReg) {
         int category = ssaSpec.getCategory();
         return !(spansParamRange(ropReg, category)
                 || mapper.interferes(ssaSpec, ropReg));
     }
+
     /**
-     * Returns true if the specified Rop register + category
+     * Returns true if the specified rop register + category
      * will cross the boundry between the lower {@code paramWidth}
      * registers reserved for method params and the upper registers. We cannot
      * allocate a register that spans the param block and the normal block,
      * because we will be moving the param block to high registers later.
-     * 
+     *
      * @param ssaReg register in new namespace
      * @param category width that the register will have
-     * @return true in the case noted above.
+     * @return {@code true} in the case noted above
      */
     private boolean spansParamRange(int ssaReg, int category) {
         return ((ssaReg < paramRangeEnd)
@@ -583,6 +585,7 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
 
             /**
              * This method collects three types of instructions:
+             *
              * 1) Adds a local variable assignment to the
              *    {@code localVariables} map.
              * 2) Add move-result-pseudo to the
@@ -627,16 +630,16 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
     }
 
     /**
-     * Adds a mapping from an SSA register to a Rop register.
+     * Adds a mapping from an SSA register to a rop register.
      * {@link #canMapReg} should have already been called.
      *
      * @param ssaSpec {@code non-null;} SSA register to map from
-     * @param ropReg {@code >=0;} Rop register to map to
+     * @param ropReg {@code >=0;} rop register to map to
      */
     private void addMapping(RegisterSpec ssaSpec, int ropReg) {
         int ssaReg = ssaSpec.getReg();
 
-        // An assertion
+        // An assertion.
         if (ssaRegsMapped.get(ssaReg) || !canMapReg(ssaSpec, ropReg)) {
             throw new RuntimeException(
                     "attempt to add invalid register mapping");
@@ -656,7 +659,7 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
 
     /**
      * Maps the source registers of the specified instruction such that they
-     * will fall in a contiguous range in Rop form. Moves are inserted as
+     * will fall in a contiguous range in rop form. Moves are inserted as
      * necessary to allow the range to be allocated.
      *
      * @param insn {@code non-null;} insn whos sources to process
@@ -689,17 +692,20 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
 
                 int szSimilar = similarRegisters.size();
 
-                // Try to map all SSA registers also associated with this local
+                /*
+                 * Try to map all SSA registers also associated with
+                 * this local.
+                 */
                 for (int j = 0; j < szSimilar; j++) {
                     RegisterSpec similarSpec = similarRegisters.get(j);
                     int similarReg = similarSpec.getReg();
 
-                    // ...and don't map anything that's also a source...
+                    // Don't map anything that's also a source.
                     if (-1 != sources.indexOfRegister(similarReg)) {
                         continue;
                     }
 
-                    // Registers left unmapped will get handled later
+                    // Registers left unmapped will get handled later.
                     tryMapReg(similarSpec, curRopReg, category);
                 }
             }
@@ -709,9 +715,9 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
     /**
      * Find a contiguous rop register range that fits the specified
      * instruction's sources. First, try to center the range around
-     * sources that have already been mapped to Rop registers. If that fails,
+     * sources that have already been mapped to rop registers. If that fails,
      * just find a new contiguous range that doesn't interfere.
-     * 
+     *
      * @param insn {@code non-null;} the insn whose sources need to
      * fit. Must be last insn in basic block.
      * @return {@code >= 0;} rop register of start of range
@@ -730,7 +736,7 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
             rangeLength += categoriesForIndex[i];
         }
 
-        // The highest score of fits tried so far
+        // the highest score of fits tried so far
         int maxScore = Integer.MIN_VALUE;
         // the high scoring range's start
         int resultRangeStart = -1;
@@ -739,7 +745,7 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
 
         /*
          * First, go through each source that's already been mapped. Try
-         * to center the range around the Rop register this source is mapped
+         * to center the range around the rop register this source is mapped
          * to.
          */
         int rangeStartOffset = 0;
@@ -797,7 +803,7 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
         }
 
         /*
-         * Now, insert any moves required
+         * Now, insert any moves required.
          */
 
         for (int i = resultMovesRequired.nextSetBit(0); i >= 0;
@@ -814,13 +820,13 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
      * around an already-mapped source register;
      *
      * @param insn {@code non-null;} insn to build range for
-     * @param rangeLength {@code >=0;} length required in register units.
+     * @param rangeLength {@code >=0;} length required in register units
      * @param categoriesForIndex {@code non-null;} indexed by source index;
-     * the category for each source.
+     * the category for each source
      * @param outMovesRequired {@code non-null;} an output parameter indexed by
      * source index that will contain the set of sources which need
-     * moves inserted.
-     * @return the rop register that starts the fitting range.
+     * moves inserted
+     * @return the rop register that starts the fitting range
      */
     private int findAnyFittingRange(NormalSsaInsn insn, int rangeLength,
             int[] categoriesForIndex, BitSet outMovesRequired) {
@@ -847,12 +853,12 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
      * @param ropReg {@code >= 0;} rop reg that begins range
      * @param insn {@code non-null;} insn to plan range for
      * @param categoriesForIndex {@code non-null;} indexed by source index;
-     * the category for each source.
+     * the category for each source
      * @param outMovesRequired {@code non-null;} an output parameter indexed by
      * source index that will contain the set of sources which need
-     * moves inserted.
+     * moves inserted
      * @return the width of the fit that that does not involve added moves or
-     * -1 if "no fit possible"
+     * {@code -1} if "no fit possible"
      */
     private int fitPlanForRange(int ropReg, NormalSsaInsn insn,
             int[] categoriesForIndex, BitSet outMovesRequired) {
@@ -862,7 +868,7 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
         IntSet liveOut = insn.getBlock().getLiveOutRegs();
         RegisterSpecList liveOutSpecs = ssaSetToSpecs(liveOut);
 
-        // An SSA reg may only be mapped into a range once
+        // An SSA reg may only be mapped into a range once.
         BitSet seen = new BitSet(ssaMeth.getRegCount());
 
         for (int i = 0; i < szSources ; i++) {
@@ -876,7 +882,7 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
 
             if (ssaRegsMapped.get(ssaReg)
                     && mapper.oldToNew(ssaReg) == ropReg) {
-                // A register already mapped appropriately
+                // This is a register that is already mapped appropriately.
                 fitWidth += category;
             } else if (rangeContainsReserved(ropReg, category)) {
                 fitWidth = -1;
@@ -884,19 +890,20 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
             } else if (!ssaRegsMapped.get(ssaReg)
                     && canMapReg(ssaSpec, ropReg)
                     && !seen.get(ssaReg)) {
-                // A register that can be mapped appropriately
+                // This is a register that can be mapped appropriately.
                 fitWidth += category;
             } else if (!mapper.areAnyPinned(liveOutSpecs, ropReg, category)
                     && !mapper.areAnyPinned(sources, ropReg, category)) {
                 /*
-                 * A source that can be moved
-                 * We can insert a move as long as:
+                 * This is a source that can be moved. We can insert a
+                 * move as long as:
+                 *
+                 *   * no SSA register pinned to the desired rop reg
+                 *     is live out on the block
                  *
-                 *  - no SSA register pinned to the desired rop reg
-                 * is live out on the block
-                 *  - no SSA register pinned to desired rop reg is
-                 *  a source of this insn (since this may require
-                 * overlapping moves, which we can't presently handle)
+                 *   * no SSA register pinned to desired rop reg is
+                 *     a source of this insn (since this may require
+                 *     overlapping moves, which we can't presently handle)
                  */
 
                 outMovesRequired.set(i);
@@ -926,12 +933,12 @@ public class FirstFitLocalCombiningAllocator extends RegisterAllocator {
         while (iter.hasNext()) {
             result.set(i++, getDefinitionSpecForSsaReg(iter.next()));
         }
-        
+
         return result;
     }
 
     /**
-     * Gets a local item associated with an ssa register, if one exists
+     * Gets a local item associated with an ssa register, if one exists.
      *
      * @param ssaReg {@code >= 0;} SSA register
      * @return {@code null-ok;} associated local item or null
index 897cc57..cd3f7d2 100644 (file)
@@ -60,33 +60,34 @@ public class LivenessAnalyzer {
     private final InterferenceGraph interference;
 
     /** block "n" in Appel 19.17 */
-    SsaBasicBlock blockN;
+    private SsaBasicBlock blockN;
 
-    /** index of statement {@code s} in {@code blockN}*/
+    /** index of statement {@code s} in {@code blockN} */
     private int statementIndex;
 
-    /** the next function to call. one of the four constants below */
-    private int nextFunction;
+    /** the next function to call */
+    private NextFunction nextFunction;
 
-    /** constants for nextFunction */
-    static final int LIVE_IN_AT_STATEMENT = 1;
-    static final int LIVE_OUT_AT_STATEMENT = 2;
-    static final int LIVE_OUT_AT_BLOCK = 3;
-    static final int DONE = 4;
+    /** constants for {@link #nextFunction} */
+    private static enum NextFunction {
+        LIVE_IN_AT_STATEMENT,
+            LIVE_OUT_AT_STATEMENT,
+            LIVE_OUT_AT_BLOCK,
+            DONE;
+    }
 
     /**
      * Runs register liveness algorithm for a method, updating the
      * live in/out information in {@code SsaBasicBlock} instances and
      * returning an interference graph.
      *
-     * @param ssaMeth {@code non-null;} Method to process.
+     * @param ssaMeth {@code non-null;} method to process
      * @return {@code non-null;} interference graph indexed by SSA
-     * registers in both directions.
+     * registers in both directions
      */
     public static InterferenceGraph constructInterferenceGraph(
             SsaMethod ssaMeth) {
         int szRegs = ssaMeth.getRegCount();
-
         InterferenceGraph interference = new InterferenceGraph(szRegs);
 
         for (int i = 0; i < szRegs; i++) {
@@ -109,10 +110,12 @@ public class LivenessAnalyzer {
      */
     private LivenessAnalyzer(SsaMethod ssaMeth, int reg,
             InterferenceGraph interference) {
+        int blocksSz = ssaMeth.getBlocks().size();
+
         this.ssaMeth = ssaMeth;
         this.regV = reg;
-        visitedBlocks = new BitSet(ssaMeth.getBlocks().size());
-        liveOutBlocks = new BitSet(ssaMeth.getBlocks().size());
+        visitedBlocks = new BitSet(blocksSz);
+        liveOutBlocks = new BitSet(blocksSz);
         this.interference = interference;
     }
 
@@ -122,20 +125,20 @@ public class LivenessAnalyzer {
      * serves as the dispatcher instead.
      */
     private void handleTailRecursion() {
-        while (nextFunction != DONE) {
+        while (nextFunction != NextFunction.DONE) {
             switch (nextFunction) {
                 case LIVE_IN_AT_STATEMENT:
-                    nextFunction = DONE;
+                    nextFunction = NextFunction.DONE;
                     liveInAtStatement();
                     break;
 
                 case LIVE_OUT_AT_STATEMENT:
-                    nextFunction = DONE;
+                    nextFunction = NextFunction.DONE;
                     liveOutAtStatement();
                     break;
 
                 case LIVE_OUT_AT_BLOCK:
-                    nextFunction = DONE;
+                    nextFunction = NextFunction.DONE;
                     liveOutAtBlock();
                     break;
 
@@ -151,7 +154,7 @@ public class LivenessAnalyzer {
         List<SsaInsn> useList = ssaMeth.getUseListForRegister(regV);
 
         for (SsaInsn insn : useList) {
-            nextFunction = DONE;
+            nextFunction = NextFunction.DONE;
 
             if (insn instanceof PhiInsn) {
                 // If s is a phi-function with V as it's ith argument.
@@ -161,7 +164,7 @@ public class LivenessAnalyzer {
                          phi.predBlocksForReg(regV, ssaMeth)) {
                     blockN = pred;
 
-                    nextFunction = LIVE_OUT_AT_BLOCK;
+                    nextFunction = NextFunction.LIVE_OUT_AT_BLOCK;
                     handleTailRecursion();
                 }
             } else {
@@ -173,7 +176,7 @@ public class LivenessAnalyzer {
                             "insn not found in it's own block");
                 }
 
-                nextFunction = LIVE_IN_AT_STATEMENT;
+                nextFunction = NextFunction.LIVE_IN_AT_STATEMENT;
                 handleTailRecursion();
             }
         }
@@ -182,7 +185,7 @@ public class LivenessAnalyzer {
         while ((nextLiveOutBlock = liveOutBlocks.nextSetBit(0)) >= 0) {
             blockN = ssaMeth.getBlocks().get(nextLiveOutBlock);
             liveOutBlocks.clear(nextLiveOutBlock);
-            nextFunction = LIVE_OUT_AT_BLOCK;
+            nextFunction = NextFunction.LIVE_OUT_AT_BLOCK;
             handleTailRecursion();
         }
     }
@@ -202,7 +205,7 @@ public class LivenessAnalyzer {
 
             // Live out at last statement in blockN
             statementIndex = insns.size() - 1;
-            nextFunction = LIVE_OUT_AT_STATEMENT;
+            nextFunction = NextFunction.LIVE_OUT_AT_STATEMENT;
         }
     }
 
@@ -221,7 +224,7 @@ public class LivenessAnalyzer {
         } else {
             // Let s' be the statement preceeding s
             statementIndex -= 1;
-            nextFunction = LIVE_OUT_AT_STATEMENT;
+            nextFunction = NextFunction.LIVE_OUT_AT_STATEMENT;
         }
     }
 
@@ -236,7 +239,7 @@ public class LivenessAnalyzer {
             if (rs != null) {
                 interference.add(regV, rs.getReg());
             }
-            nextFunction = LIVE_IN_AT_STATEMENT;
+            nextFunction = NextFunction.LIVE_IN_AT_STATEMENT;
         }
     }