1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License.
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.android.dx.ssa;
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
19e31ed7e916d212840dd5639afa01938bea58b2b8jeffhaoimport com.android.dx.rop.code.LocalItem;
20e31ed7e916d212840dd5639afa01938bea58b2b8jeffhaoimport com.android.dx.rop.code.PlainInsn;
21e31ed7e916d212840dd5639afa01938bea58b2b8jeffhaoimport com.android.dx.rop.code.RegisterSpec;
22e31ed7e916d212840dd5639afa01938bea58b2b8jeffhaoimport com.android.dx.rop.code.RegisterSpecList;
23e31ed7e916d212840dd5639afa01938bea58b2b8jeffhaoimport com.android.dx.rop.code.Rops;
24e31ed7e916d212840dd5639afa01938bea58b2b8jeffhaoimport com.android.dx.rop.code.SourcePosition;
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.Type;
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.IntList;
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.ArrayList;
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.BitSet;
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.HashMap;
30e31ed7e916d212840dd5639afa01938bea58b2b8jeffhaoimport java.util.HashSet;
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Complete transformation to SSA form by renaming all registers accessed.<p>
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See Appel algorithm 19.7<p>
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unlike the original algorithm presented in Appel, this renamer converts
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to a new flat (versionless) register space. The "version 0" registers,
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * which represent the initial state of the Rop registers and should never
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * actually be meaningfully accessed in a legal program, are represented
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * as the first N registers in the SSA namespace. Subsequent assignments
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * are assigned new unique names. Note that the incoming Rop representation
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * has a concept of register widths, where 64-bit values are stored into
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * two adjoining Rop registers. This adjoining register representation is
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ignored in SSA form conversion and while in SSA form, each register can be e
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * either 32 or 64 bits wide depending on use. The adjoining-register
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * represention is re-created later when converting back to Rop form. <p>
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * But, please note, the SSA Renamer's ignoring of the adjoining-register ROP
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * representation means that unaligned accesses to 64-bit registers are not
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * supported. For example, you cannot do a 32-bit operation on a portion of
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a 64-bit register. This will never be observed to happen when coming
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * from Java code, of course.<p>
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The implementation here, rather than keeping a single register version
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * stack for the entire method as the dom tree is walked, instead keeps
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a mapping table for the current block being processed. Once the
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * current block has been processed, this mapping table is then copied
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and used as the initial state for child blocks.<p>
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
6164986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornsteinpublic class SsaRenamer implements Runnable {
6264986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein    /** debug flag */
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final boolean DEBUG = false;
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
6564986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein    /** method we're processing */
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final SsaMethod ssaMeth;
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** next available SSA register */
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int nextSsaReg;
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** the number of original rop registers */
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final int ropRegCount;
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
74e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao    /** work only on registers above this value */
75e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao    private int threshold;
76e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
7864986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein     * indexed by block index; register version state for each block start.
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * This list is updated by each dom parent for its children. The only
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * sub-arrays that exist at any one time are the start states for blocks
8199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * yet to be processed by a {@code BlockRenamer} instance.
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final RegisterSpec[][] startsForBlocks;
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** map of SSA register number to debug (local var names) or null of n/a */
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final ArrayList<LocalItem> ssaRegToLocalItems;
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
8964986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein     * maps SSA registers back to the original rop number. Used for
9064986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein     * debug only.
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private IntList ssaRegToRopReg;
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs an instance of the renamer
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
9799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param ssaMeth {@code non-null;} un-renamed SSA method that will
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * be renamed.
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
10064986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein    public SsaRenamer(SsaMethod ssaMeth) {
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ropRegCount = ssaMeth.getRegCount();
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.ssaMeth = ssaMeth;
10464986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Reserve the first N registers in the SSA register space for
10764986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein         * "version 0" registers.
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        nextSsaReg = ropRegCount;
110e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao        threshold = 0;
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        startsForBlocks = new RegisterSpec[ssaMeth.getBlocks().size()][];
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ssaRegToLocalItems = new ArrayList<LocalItem>();
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (DEBUG) {
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ssaRegToRopReg = new IntList(ropRegCount);
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Appel 19.7
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Initialization:
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *   for each variable a        // register i
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *      Count[a] <- 0           // nextSsaReg, flattened
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *      Stack[a] <- 0           // versionStack
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *      push 0 onto Stack[a]
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // top entry for the version stack is version 0
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        RegisterSpec[] initialRegMapping = new RegisterSpec[ropRegCount];
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < ropRegCount; i++) {
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // everyone starts with a version 0 register
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            initialRegMapping[i] = RegisterSpec.make(i, Type.VOID);
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (DEBUG) {
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                ssaRegToRopReg.add(i);
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Initial state for entry block
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        startsForBlocks[ssaMeth.getEntryBlockIndex()] = initialRegMapping;
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
146e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao    * Constructs an instance of the renamer with threshold set
147e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao    *
148e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao    * @param ssaMeth {@code non-null;} un-renamed SSA method that will
149e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao    * be renamed.
150e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao    * @param thresh registers below this number are unchanged
151e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao    */
152e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao   public SsaRenamer(SsaMethod ssaMeth, int thresh) {
153e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao       this(ssaMeth);
154e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao       threshold = thresh;
155e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao   }
156e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao
157e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao    /**
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Performs renaming transformation, modifying the method's instructions
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * in-place.
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void run() {
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Rename each block in dom-tree DFS order.
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ssaMeth.forEachBlockDepthFirstDom(new SsaBasicBlock.Visitor() {
16441aecd0a6bfea1e9a6713014b2b3d56fec8c552cDan Bornstein            public void visitBlock (SsaBasicBlock block,
16541aecd0a6bfea1e9a6713014b2b3d56fec8c552cDan Bornstein                    SsaBasicBlock unused) {
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                new BlockRenamer(block).process();
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        });
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ssaMeth.setNewRegCount(nextSsaReg);
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ssaMeth.onInsnsChanged();
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (DEBUG) {
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.out.println("SSA\tRop");
17564986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein            /*
17664986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein             * We're going to compute the version of the rop register
17764986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein             * by keeping a running total of how many times the rop
17864986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein             * register has been mapped.
17964986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein             */
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int[] versions = new int[ropRegCount];
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int sz = ssaRegToRopReg.size();
18341aecd0a6bfea1e9a6713014b2b3d56fec8c552cDan Bornstein            for (int i = 0; i < sz; i++) {
1844b4413ab3d8de5805276cfcde3d7f535d9f64e85Dan Bornstein                int ropReg = ssaRegToRopReg.get(i);
1854b4413ab3d8de5805276cfcde3d7f535d9f64e85Dan Bornstein                System.out.println(i + "\t" + ropReg + "["
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        + versions[ropReg] + "]");
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                versions[ropReg]++;
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
19364986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein     * Duplicates a RegisterSpec array.
19464986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein     *
19599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param orig {@code non-null;} array to duplicate
19699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} new instance
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static  RegisterSpec[] dupArray(RegisterSpec[] orig) {
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        RegisterSpec[] copy = new RegisterSpec[orig.length];
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        System.arraycopy(orig, 0, copy, 0, orig.length);
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return copy;
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets a local variable item for a specified register.
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param ssaReg register in SSA name space
21099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code null-ok;} Local variable name or null if none
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private LocalItem getLocalForNewReg(int ssaReg) {
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (ssaReg < ssaRegToLocalItems.size()) {
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return ssaRegToLocalItems.get(ssaReg);
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return null;
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Records a debug (local variable) name for a specified register.
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param ssaReg non-null named register spec in SSA name space
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void setNameForSsaReg(RegisterSpec ssaReg) {
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int reg = ssaReg.getReg();
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LocalItem local = ssaReg.getLocalItem();
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ssaRegToLocalItems.ensureCapacity(reg + 1);
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        while (ssaRegToLocalItems.size() <= reg) {
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ssaRegToLocalItems.add(null);
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ssaRegToLocalItems.set(reg, local);
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
238e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao     * Returns true if this SSA register is below the specified threshold.
239e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao     * Used when most code is already in SSA form, and renaming is needed only
240e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao     * for registers above a certain threshold.
241e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao     *
242e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao     * @param ssaReg the SSA register in question
243e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao     * @return {@code true} if its register number is below the threshold
244e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao     */
245e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao    private boolean isBelowThresholdRegister(int ssaReg) {
246e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao        return ssaReg < threshold;
247e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao    }
248e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao
249e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao    /**
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns true if this SSA register is a "version 0"
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * register. All version 0 registers are assigned the first N register
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * numbers, where N is the count of original rop registers.
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param ssaReg the SSA register in question
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return true if it is a version 0 register.
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private boolean isVersionZeroRegister(int ssaReg) {
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return ssaReg < ropRegCount;
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
26264986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein     * Returns true if a and b are equal or are both null.
26364986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein     *
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param a null-ok
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param b null-ok
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return Returns true if a and b are equal or are both null
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static boolean equalsHandlesNulls(Object a, Object b) {
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return a == b ||  (a != null && a.equals(b));
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Processes all insns in a block and renames their registers
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * as appropriate.
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private class BlockRenamer implements SsaInsn.Visitor{
27799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        /** {@code non-null;} block we're processing. */
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private final SsaBasicBlock block;
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
28164986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein         * {@code non-null;} indexed by old register name. The current
28264986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein         * top of the version stack as seen by this block. It's
28364986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein         * initialized from the ending state of its dom parent,
28464986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein         * updated as the block's instructions are processed, and then
28564986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein         * copied to each one of its dom children.
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private final RegisterSpec[] currentMapping;
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
29064986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein         * contains the set of moves we need to keep to preserve local
29164986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein         * var info. All other moves will be deleted.
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private final HashSet<SsaInsn> movesToKeep;
294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
29664986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein         * maps the set of insns to replace after renaming is finished
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * on the block.
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private final HashMap<SsaInsn, SsaInsn> insnsToReplace;
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private final RenamingMapper mapper;
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
30499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project         * Constructs a block renamer instance. Call {@code process}
305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * to process.
306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
30799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project         * @param block {@code non-null;} block to process
308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        BlockRenamer(final SsaBasicBlock block) {
310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.block = block;
311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            currentMapping = startsForBlocks[block.getIndex()];
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            movesToKeep = new HashSet<SsaInsn>();
313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insnsToReplace = new HashMap<SsaInsn, SsaInsn>();
314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            mapper =  new RenamingMapper();
315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // We don't need our own start state anymore
317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            startsForBlocks[block.getIndex()] = null;
318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Provides a register mapping between the old register space
322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * and the current renaming mapping. The mapping is updated
323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * as the current block's instructions are processed.
324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private class RenamingMapper extends RegisterMapper {
32664986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein            public RenamingMapper() {
32764986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein                // This space intentionally left blank.
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /** {@inheritDoc} */
331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            @Override
332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            public int getNewRegisterCount() {
333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return nextSsaReg;
334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /** {@inheritDoc} */
337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            @Override
338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            public RegisterSpec map(RegisterSpec registerSpec) {
339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (registerSpec == null) return null;
340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                int reg = registerSpec.getReg();
342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
34364986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein                // For debugging: assert that the mapped types are compatible.
34441aecd0a6bfea1e9a6713014b2b3d56fec8c552cDan Bornstein                if (DEBUG) {
345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    RegisterSpec newVersion = currentMapping[reg];
346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    if (newVersion.getBasicType() != Type.BT_VOID
347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            && registerSpec.getBasicFrameType()
348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                != newVersion.getBasicFrameType()) {
349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        throw new RuntimeException(
351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                "mapping registers of incompatible types! "
352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                + registerSpec
353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                + " " + currentMapping[reg]);
354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return registerSpec.withReg(currentMapping[reg].getReg());
358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Renames all the variables in this block and inserts appriopriate
363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * phis in successor blocks.
364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public void process() {
366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * From Appel:
368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             *
369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Rename(n) =
370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             *   for each statement S in block n   // 'statement' in 'block'
371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            block.forEachInsn(this);
374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            updateSuccessorPhis();
376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
37764986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein            // Delete all move insns in this block.
378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ArrayList<SsaInsn> insns = block.getInsns();
379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int szInsns = insns.size();
380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = szInsns - 1; i >= 0 ; i--) {
382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                SsaInsn insn = insns.get(i);
383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                SsaInsn replaceInsn;
384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                replaceInsn = insnsToReplace.get(insn);
386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (replaceInsn != null) {
38864986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein                    insns.set(i, replaceInsn);
389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } else if (insn.isNormalMoveInsn()
390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        && !movesToKeep.contains(insn)) {
391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    insns.remove(i);
392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
39564986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein            // Store the start states for our dom children.
396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            boolean first = true;
39741aecd0a6bfea1e9a6713014b2b3d56fec8c552cDan Bornstein            for (SsaBasicBlock child : block.getDomChildren()) {
398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (child != block) {
39964986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein                    // Don't bother duplicating the array for the first child.
40064986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein                    RegisterSpec[] childStart = first ? currentMapping
40164986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein                        : dupArray(currentMapping);
402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    startsForBlocks[child.getIndex()] = childStart;
404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    first = false;
405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
40864986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein            // currentMapping is owned by a child now.
409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Enforces a few contraints when a register mapping is added.
413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * <ol>
415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * <li> Ensures that all new SSA registers specs in the mapping
416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * table with the same register number are identical. In effect, once
417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * an SSA register spec has received or lost a local variable name,
418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * then every old-namespace register that maps to it should gain or
419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * lose its local variable name as well.
420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * <li> Records the local name associated with the
421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * register so that a register is never associated with more than one
422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * local.
423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * <li> ensures that only one SSA register
424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * at a time is considered to be associated with a local variable. When
42599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project         * {@code currentMapping} is updated and the newly added element
426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * is named, strip that name from any other SSA registers.
427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * </ol>
428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
42999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project         * @param ropReg {@code >= 0;} rop register number
43099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project         * @param ssaReg {@code non-null;} an SSA register that has just
43199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project         * been added to {@code currentMapping}
432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private void addMapping(int ropReg, RegisterSpec ssaReg) {
434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int ssaRegNum = ssaReg.getReg();
435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LocalItem ssaRegLocal = ssaReg.getLocalItem();
436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            currentMapping[ropReg] = ssaReg;
438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Ensure all SSA register specs with the same reg are identical.
441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = currentMapping.length - 1; i >= 0; i--) {
443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                RegisterSpec cur = currentMapping[i];
444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (ssaRegNum == cur.getReg()) {
446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    currentMapping[i] = ssaReg;
447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
45064986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein            // All further steps are for registers with local information.
451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (ssaRegLocal == null) {
452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return;
453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
45564986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein            // Record that this SSA reg has been associated with a local.
456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            setNameForSsaReg(ssaReg);
457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
45864986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein            // Ensure that no other SSA regs are associated with this local.
459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = currentMapping.length - 1; i >= 0; i--) {
460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                RegisterSpec cur = currentMapping[i];
461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (ssaRegNum != cur.getReg()
463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        && ssaRegLocal.equals(cur.getLocalItem())) {
464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    currentMapping[i] = cur.withLocalItem(null);
465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * {@inheritDoc}
471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Phi insns have their result registers renamed.
47364986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein         */
474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public void visitPhiInsn(PhiInsn phi) {
475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* don't process sources for phi's */
476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            processResultReg(phi);
477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * {@inheritDoc}
481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Move insns are treated as a simple mapping operation, and
483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * will later be removed unless they represent a local variable
484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * assignment. If they represent a local variable assignement, they
485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * are preserved.
486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public void visitMoveInsn(NormalSsaInsn insn) {
488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
48964986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein             * For moves: copy propogate the move if we can, but don't
490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * if we need to preserve local variable info and the
491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * result has a different name than the source.
492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            RegisterSpec ropResult = insn.getResult();
495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int ropResultReg = ropResult.getReg();
496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int ropSourceReg = insn.getSources().get(0).getReg();
497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insn.mapSourceRegisters(mapper);
499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int ssaSourceReg = insn.getSources().get(0).getReg();
500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
50164986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein            LocalItem sourceLocal
50264986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein                = currentMapping[ropSourceReg].getLocalItem();
503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LocalItem resultLocal = ropResult.getLocalItem();
504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * A move from a register that's currently associated with a local
507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * to one that will not be associated with a local does not need
508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * to be preserved, but the local association should remain.
509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Hence, we inherit the sourceLocal where the resultLocal is null.
510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LocalItem newLocal
51364986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein                = (resultLocal == null) ? sourceLocal : resultLocal;
514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LocalItem associatedLocal = getLocalForNewReg(ssaSourceReg);
515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
51664986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein            /*
51764986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein             * If we take the new local, will only one local have ever
51864986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein             * been associated with this SSA reg?
51964986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein             */
520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            boolean onlyOneAssociatedLocal
521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    = associatedLocal == null || newLocal == null
522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    || newLocal.equals(associatedLocal);
52364986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein
524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
52564986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein             * If we're going to copy-propogate, then the ssa register
52664986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein             * spec that's going to go into the mapping is made up of
52764986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein             * the source register number mapped from above, the type
528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * of the result, and the name either from the result (if
529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * specified) or inherited from the existing mapping.
530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             *
53164986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein             * The move source has incomplete type information in null
53264986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein             * object cases, so the result type is used.
533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            RegisterSpec ssaReg
535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    = RegisterSpec.makeLocalOptional(
536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        ssaSourceReg, ropResult.getType(), newLocal);
537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (!Optimizer.getPreserveLocals() || (onlyOneAssociatedLocal
539e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao                    && equalsHandlesNulls(newLocal, sourceLocal)) &&
540e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao                    threshold == 0) {
541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                /*
542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * We don't have to keep this move to preserve local
543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * information. Either the name is the same, or the result
544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * register spec is unnamed.
545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 */
546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                addMapping(ropResultReg, ssaReg);
548e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao            } else if (onlyOneAssociatedLocal && sourceLocal == null &&
549e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao                    threshold == 0) {
550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                /*
551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * The register was previously unnamed. This means that a
552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * local starts after it's first assignment in SSA form
553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 */
554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
55564986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein                RegisterSpecList ssaSources = RegisterSpecList.make(
556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        RegisterSpec.make(ssaReg.getReg(),
557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                ssaReg.getType(), newLocal));
558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                SsaInsn newInsn
560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        = SsaInsn.makeFromRop(
561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            new PlainInsn(Rops.opMarkLocal(ssaReg),
562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            SourcePosition.NO_INFO, null, ssaSources),block);
563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                insnsToReplace.put(insn, newInsn);
565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
56664986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein                // Just map as above.
567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                addMapping(ropResultReg, ssaReg);
568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {
569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                /*
57064986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein                 * Do not copy-propogate, since the two registers have
57164986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein                 * two different local-variable names.
572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 */
573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                processResultReg(insn);
574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                movesToKeep.add(insn);
576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * {@inheritDoc}
581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * All insns that are not move or phi insns have their source registers
583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * mapped ot the current mapping. Their result registers are then
584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * renamed to a new SSA register which is then added to the current
585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * register mapping.
586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public void visitNonMoveInsn(NormalSsaInsn insn) {
588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* for each use of some variable X in S */
589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insn.mapSourceRegisters(mapper);
590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            processResultReg(insn);
592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Renames the result register of this insn and updates the
596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * current register mapping. Does nothing if this insn has no result.
597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Applied to all non-move insns.
598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @param insn insn to process.
600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        void processResultReg(SsaInsn insn) {
602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            RegisterSpec ropResult = insn.getResult();
603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (ropResult == null) {
605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return;
606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int ropReg = ropResult.getReg();
609e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao            if (isBelowThresholdRegister(ropReg)) {
610e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao                return;
611e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao            }
612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            insn.changeResultReg(nextSsaReg);
614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            addMapping(ropReg, insn.getResult());
615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (DEBUG) {
617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                ssaRegToRopReg.add(ropReg);
618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            nextSsaReg++;
621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Updates the phi insns in successor blocks with operands based
625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * on the current mapping of the rop register the phis represent.
626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private void updateSuccessorPhis() {
628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            PhiInsn.Visitor visitor = new PhiInsn.Visitor() {
629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                public void visitPhiInsn (PhiInsn insn) {
630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    int ropReg;
631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    ropReg = insn.getRopResultReg();
633e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao                    if (isBelowThresholdRegister(ropReg)) {
634e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao                        return;
635e31ed7e916d212840dd5639afa01938bea58b2b8jeffhao                    }
636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    /*
63864986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein                     * Never add a version 0 register as a phi
63964986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein                     * operand. Version 0 registers represent the
64064986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein                     * initial register state, and thus are never
64164986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein                     * significant. Furthermore, the register liveness
64264986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein                     * algorithm doesn't properly count them as "live
64364986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein                     * in" at the beginning of the method.
644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     */
645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    RegisterSpec stackTop = currentMapping[ropReg];
647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    if (!isVersionZeroRegister(stackTop.getReg())) {
648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        insn.addPhiOperand(stackTop, block);
649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            };
652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            BitSet successors = block.getSuccessors();
654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = successors.nextSetBit(0); i >= 0;
655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    i = successors.nextSetBit(i + 1)) {
656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                SsaBasicBlock successor = ssaMeth.getBlocks().get(i);
657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                successor.forEachPhiInsn(visitor);
658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
662