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