FirstFitLocalCombiningAllocator.java revision 1acb3f560b45df68d5acdcb2759de1f78ef5da7c
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.back; 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.*; 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstInteger; 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.ssa.InterferenceRegisterMapper; 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.ssa.RegisterMapper; 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.ssa.SsaInsn; 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.ssa.SsaMethod; 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.ssa.NormalSsaInsn; 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.ssa.PhiInsn; 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.ssa.Optimizer; 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.ssa.SsaBasicBlock; 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.IntSet; 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.IntIterator; 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.ArrayList; 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.BitSet; 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Map; 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.TreeMap; 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Allocates registers in a first-fit fashion, with the bottom reserved for 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method parameters and all SSAregisters representing the same local variable 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * kept together if possible. 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class FirstFitLocalCombiningAllocator extends RegisterAllocator { 4399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** local debug flag */ 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static final boolean DEBUG = false; 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** maps local variable to a list of associated SSA registers */ 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final Map<LocalItem, ArrayList<RegisterSpec>> localVariables; 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** list of move-result-pesudo instructions seen in this method */ 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final ArrayList<NormalSsaInsn> moveResultPseudoInsns; 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** list of invoke-range instructions seen in this method */ 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final ArrayList<NormalSsaInsn> invokeRangeInsns; 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 556ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao /** list of phi instructions seen in this method */ 566ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao private final ArrayList<PhiInsn> phiInsns; 576ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** indexed by SSA reg; the set of SSA regs we've mapped */ 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final BitSet ssaRegsMapped; 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** Register mapper which will be our result */ 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final InterferenceRegisterMapper mapper; 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 6464986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein /** end of rop registers range (starting at 0) reserved for parameters */ 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final int paramRangeEnd; 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 6764986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein /** set of rop registers reserved for parameters or local variables */ 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final BitSet reservedRopRegs; 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 7064986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein /** set of rop registers that have been used by anything */ 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final BitSet usedRopRegs; 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 7364986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein /** true if converter should take steps to minimize rop-form registers */ 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final boolean minimizeRegisters; 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs instance. 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 7999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param ssaMeth {@code non-null;} method to process 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param interference non-null interference graph for SSA registers 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param minimizeRegisters true if converter should take steps to 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * minimize rop-form registers 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public FirstFitLocalCombiningAllocator( 8599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project SsaMethod ssaMeth, InterferenceGraph interference, 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean minimizeRegisters) { 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project super(ssaMeth, interference); 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ssaRegsMapped = new BitSet(ssaMeth.getRegCount()); 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mapper = new InterferenceRegisterMapper( 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project interference, ssaMeth.getRegCount()); 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.minimizeRegisters = minimizeRegisters; 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Reserve space for the params at the bottom of the register 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * space. Later, we'll flip the params to the end of the register 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * space. 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project paramRangeEnd = ssaMeth.getParamWidth(); 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project reservedRopRegs = new BitSet(paramRangeEnd * 2); 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project reservedRopRegs.set(0, paramRangeEnd); 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project usedRopRegs = new BitSet(paramRangeEnd * 2); 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project localVariables = new TreeMap<LocalItem, ArrayList<RegisterSpec>>(); 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project moveResultPseudoInsns = new ArrayList<NormalSsaInsn>(); 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project invokeRangeInsns = new ArrayList<NormalSsaInsn>(); 1106ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao phiInsns = new ArrayList<PhiInsn>(); 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean wantsParamsMovedHigh() { 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public RegisterMapper allocateRegisters() { 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project analyzeInstructions(); 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (DEBUG) { 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printLocalVars(); 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 12999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project if (DEBUG) System.out.println("--->Mapping local-associated params"); 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project handleLocalAssociatedParams(); 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 13299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project if (DEBUG) System.out.println("--->Mapping other params"); 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project handleUnassociatedParameters(); 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 13599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project if (DEBUG) System.out.println("--->Mapping invoke-range"); 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project handleInvokeRangeInsns(); 13764986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein 13899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project if (DEBUG) { 13999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project System.out.println("--->Mapping local-associated non-params"); 14099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project } 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project handleLocalAssociatedOther(); 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 14399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project if (DEBUG) System.out.println("--->Mapping check-cast results"); 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project handleCheckCastResults(); 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1466ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao if (DEBUG) System.out.println("--->Mapping phis"); 1476ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao handlePhiInsns(); 1486ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao 14999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project if (DEBUG) System.out.println("--->Mapping others"); 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project handleNormalUnassociated(); 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return mapper; 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Dumps local variable table to stdout for debugging. 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void printLocalVars() { 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.out.println("Printing local vars"); 16041aecd0a6bfea1e9a6713014b2b3d56fec8c552cDan Bornstein for (Map.Entry<LocalItem, ArrayList<RegisterSpec>> e : 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project localVariables.entrySet()) { 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringBuilder regs = new StringBuilder(); 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regs.append('{'); 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regs.append(' '); 16641aecd0a6bfea1e9a6713014b2b3d56fec8c552cDan Bornstein for (RegisterSpec reg : e.getValue()) { 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regs.append('v'); 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regs.append(reg.getReg()); 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regs.append(' '); 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regs.append('}'); 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.out.printf("Local: %s Registers: %s\n", e.getKey(), regs); 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 17764986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * Maps all local-associated parameters to rop registers. 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void handleLocalAssociatedParams() { 18099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project for (ArrayList<RegisterSpec> ssaRegs : localVariables.values()) { 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int sz = ssaRegs.size(); 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int paramIndex = -1; 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int paramCategory = 0; 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 18564986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein // First, find out if this local variable is a parameter. 18699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project for (int i = 0; i < sz; i++) { 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec ssaSpec = ssaRegs.get(i); 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ssaReg = ssaSpec.getReg(); 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project paramIndex = getParameterIndexForReg(ssaReg); 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (paramIndex >= 0) { 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project paramCategory = ssaSpec.getCategory(); 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project addMapping(ssaSpec, paramIndex); 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (paramIndex < 0) { 20064986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein // This local wasn't a parameter. 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 20464986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein // Any remaining local-associated registers will be mapped later. 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tryMapRegs(ssaRegs, paramIndex, paramCategory, true); 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the parameter index for SSA registers that are method parameters. 21164986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * {@code -1} is returned for non-parameter registers. 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 21399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param ssaReg {@code >=0;} SSA register to look up 21464986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * @return parameter index or {@code -1} if not a parameter 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int getParameterIndexForReg(int ssaReg) { 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SsaInsn defInsn = ssaMeth.getDefinitionForRegister(ssaReg); 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (defInsn == null) { 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 22164986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Rop opcode = defInsn.getOpcode(); 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 22464986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein // opcode == null for phi insns. 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (opcode != null && opcode.getOpcode() == RegOps.MOVE_PARAM) { 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CstInsn origInsn = (CstInsn) defInsn.getOriginalRopInsn(); 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ((CstInteger) origInsn.getConstant()).getValue(); 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 23464986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * Maps all local-associated registers that are not parameters. 23599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Tries to find an unreserved range that's wide enough for all of 23699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * the SSA registers, and then tries to map them all to that 23799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * range. If not all fit, a new range is tried until all registers 23899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * have been fit. 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void handleLocalAssociatedOther() { 24199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project for (ArrayList<RegisterSpec> specs : localVariables.values()) { 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ropReg = 0; 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean done; 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project do { 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int maxCategory = 1; 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 24864986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein // Compute max category for remaining unmapped registers. 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int sz = specs.size(); 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < sz; i++) { 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec ssaSpec = specs.get(i); 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int category = ssaSpec.getCategory(); 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!ssaRegsMapped.get(ssaSpec.getReg()) 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project && category > maxCategory) { 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project maxCategory = category; 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ropReg = findRopRegForLocal(ropReg, maxCategory); 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project done = tryMapRegs(specs, ropReg, maxCategory, true); 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 26364986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein // Increment for next call to findNext. 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ropReg++; 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } while (!done); 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Tries to map a list of SSA registers into the a rop reg, marking 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * used rop space as reserved. SSA registers that don't fit are left 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * unmapped. 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 27499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param specs {@code non-null;} SSA registers to attempt to map 27599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param ropReg {@code >=0;} rop register to map to 27664986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * @param maxAllowedCategory {@code 1..2;} maximum category 27764986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * allowed in mapping. 27864986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * @param markReserved do so if {@code true} 27964986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * @return {@code true} if all registers were mapped, {@code false} 28064986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * if some remain unmapped 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private boolean tryMapRegs( 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayList<RegisterSpec> specs, int ropReg, 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int maxAllowedCategory, boolean markReserved) { 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean remaining = false; 28699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project for (RegisterSpec spec : specs) { 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ssaRegsMapped.get(spec.getReg())) { 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean succeeded; 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project succeeded = tryMapReg(spec, ropReg, maxAllowedCategory); 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project remaining = !succeeded || remaining; 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (succeeded && markReserved) { 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // This only needs to be called once really with 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // the widest category used, but <shrug> 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project markReserved(ropReg, spec.getCategory()); 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return !remaining; 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Tries to map an SSA register to a rop register. 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 30699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param ssaSpec {@code non-null;} SSA register 30799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param ropReg {@code >=0;} rop register 30864986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * @param maxAllowedCategory {@code 1..2;} the maximum category 30964986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * that the SSA register is allowed to be 31064986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * @return {@code true} if map succeeded, {@code false} if not 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private boolean tryMapReg(RegisterSpec ssaSpec, int ropReg, 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int maxAllowedCategory) { 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ssaSpec.getCategory() <= maxAllowedCategory 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project && !ssaRegsMapped.get(ssaSpec.getReg()) 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project && canMapReg(ssaSpec, ropReg)) { 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project addMapping(ssaSpec, ropReg); 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 32564986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * Marks a range of rop registers as "reserved for a local variable." 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 32799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param ropReg {@code >= 0;} rop register to reserve 32899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param category {@code > 0;} width to reserve 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void markReserved(int ropReg, int category) { 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project reservedRopRegs.set(ropReg, ropReg + category, true); 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 33564986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * Checks to see if any rop registers in the specified range are reserved 33664986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * for local variables or parameters. 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 33864986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * @param ropRangeStart {@code >= 0;} lowest rop register 33964986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * @param width {@code > 0;} number of rop registers in range. 34064986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * @return {@code true} if any register in range is marked reserved 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private boolean rangeContainsReserved(int ropRangeStart, int width) { 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = ropRangeStart; i < (ropRangeStart + width); i++) { 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (reservedRopRegs.get(i)) { 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 35264986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * Returns true if given rop register represents the {@code this} pointer 35364986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * for a non-static method. 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param startReg rop register 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return true if the "this" pointer is located here. 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private boolean isThisPointerReg(int startReg) { 35964986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein // "this" is always the first parameter. 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return startReg == 0 && !ssaMeth.isStatic(); 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 36464986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * Finds a range of unreserved rop registers. 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 36664986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * @param startReg {@code >= 0;} a rop register to start the search at 36799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param width {@code > 0;} the width, in registers, required. 36899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code >= 0;} start of available register range. 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int findNextUnreservedRopReg(int startReg, int width) { 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (minimizeRegisters && !isThisPointerReg(startReg)) { 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return startReg; 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int reg; 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project reg = reservedRopRegs.nextClearBit(startReg); 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (true) { 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i = 1; 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (i < width && !reservedRopRegs.get(reg + i)) { 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project i++; 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (i == width) { 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return reg; 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project reg = reservedRopRegs.nextClearBit(reg + i); 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Finds a range of rop regs that can be used for local variables. 39664986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * If {@code MIX_LOCALS_AND_OTHER} is {@code false}, this means any 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * rop register that has not yet been used. 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 39964986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * @param startReg {@code >= 0;} a rop register to start the search at 40099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param width {@code > 0;} the width, in registers, required. 40199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code >= 0;} start of available register range. 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int findRopRegForLocal(int startReg, int width) { 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (minimizeRegisters && !isThisPointerReg(startReg)) { 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return startReg; 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int reg; 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project reg = usedRopRegs.nextClearBit(startReg); 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (true) { 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i = 1; 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (i < width && !usedRopRegs.get(reg + i)) { 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project i++; 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (i == width) { 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return reg; 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project reg = usedRopRegs.nextClearBit(reg + i); 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Maps any parameter that isn't local-associated, which can happen 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in the case where there is no java debug info. 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void handleUnassociatedParameters() { 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int szSsaRegs = ssaMeth.getRegCount(); 43399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int ssaReg = 0; ssaReg < szSsaRegs; ssaReg++) { 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ssaRegsMapped.get(ssaReg)) { 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // We already did this one above 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int paramIndex = getParameterIndexForReg(ssaReg); 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec ssaSpec = getDefinitionSpecForSsaReg(ssaReg); 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (paramIndex >= 0) { 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project addMapping(ssaSpec, paramIndex); 44564986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein } 446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Handles all insns that want a register range for their sources. 451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void handleInvokeRangeInsns() { 45341aecd0a6bfea1e9a6713014b2b3d56fec8c552cDan Bornstein for (NormalSsaInsn insn : invokeRangeInsns) { 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project adjustAndMapSourceRangeRange(insn); 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 45964986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * Handles check cast results to reuse the same source register if 46064986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * possible. 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void handleCheckCastResults() { 463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (NormalSsaInsn insn : moveResultPseudoInsns) { 464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec moveRegSpec = insn.getResult(); 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int moveReg = moveRegSpec.getReg(); 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project BitSet predBlocks = insn.getBlock().getPredecessors(); 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Expect one predecessor block only 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (predBlocks.cardinality() != 1) { 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SsaBasicBlock predBlock = 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ssaMeth.getBlocks().get(predBlocks.nextSetBit(0)); 475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayList<SsaInsn> insnList = predBlock.getInsns(); 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If the predecessor block has a check-cast, it will be the last 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instruction 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SsaInsn checkCastInsn = insnList.get(insnList.size() - 1); 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (checkCastInsn.getOpcode().getOpcode() != RegOps.CHECK_CAST) { 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec checkRegSpec = checkCastInsn.getSources().get(0); 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int checkReg = checkRegSpec.getReg(); 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Assume none of the register is mapped yet 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ropReg = 0; 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See if either register is already mapped. Most likely the move 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * result will be mapped already since the cast result is stored 495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in a local variable. 496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ssaRegsMapped.get(moveReg)) { 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ropReg = mapper.oldToNew(moveReg); 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (ssaRegsMapped.get(checkReg)) { 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ropReg = mapper.oldToNew(checkReg); 501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayList<RegisterSpec> ssaRegs = new ArrayList<RegisterSpec>(2); 504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ssaRegs.add(moveRegSpec); 505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ssaRegs.add(checkRegSpec); 506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int category = checkRegSpec.getCategory(); 507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (!tryMapRegs(ssaRegs, ropReg, category, false)) { 509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ropReg = findNextUnreservedRopReg(ropReg + 1, category); 510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 5156ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao * Handles all phi instructions, trying to map them to a common register. 5166ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao */ 5176ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao private void handlePhiInsns() { 5186ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao for (PhiInsn insn : phiInsns) { 5196ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao processPhiInsn(insn); 5206ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao } 5216ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao } 5226ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao 5236ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao /** 52464986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * Maps all non-parameter, non-local variable registers. 525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void handleNormalUnassociated() { 527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int szSsaRegs = ssaMeth.getRegCount(); 52899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int ssaReg = 0; ssaReg < szSsaRegs; ssaReg++) { 530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ssaRegsMapped.get(ssaReg)) { 531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // We already did this one 532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec ssaSpec = getDefinitionSpecForSsaReg(ssaReg); 536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ssaSpec == null) continue; 538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int category = ssaSpec.getCategory(); 540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Find a rop reg that does not interfere 5411acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao int ropReg = paramRangeEnd; 542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (!canMapReg(ssaSpec, ropReg)) { 543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ropReg = findNextUnreservedRopReg(ropReg + 1, category); 544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project addMapping(ssaSpec, ropReg); 547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 55199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Checks to see if {@code ssaSpec} can be mapped to 55299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code ropReg}. Checks interference graph and ensures 553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the range does not cross the parameter range. 554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 55599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param ssaSpec {@code non-null;} SSA spec 556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param ropReg prosepctive new-namespace reg 55764986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * @return {@code true} if mapping is possible 558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private boolean canMapReg(RegisterSpec ssaSpec, int ropReg) { 560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int category = ssaSpec.getCategory(); 561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return !(spansParamRange(ropReg, category) 562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project || mapper.interferes(ssaSpec, ropReg)); 563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 56464986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein 565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 56664986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * Returns true if the specified rop register + category 56799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * will cross the boundry between the lower {@code paramWidth} 568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * registers reserved for method params and the upper registers. We cannot 569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * allocate a register that spans the param block and the normal block, 570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * because we will be moving the param block to high registers later. 57164986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * 572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param ssaReg register in new namespace 573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param category width that the register will have 57464986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * @return {@code true} in the case noted above 575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private boolean spansParamRange(int ssaReg, int category) { 577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ((ssaReg < paramRangeEnd) 578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project && ((ssaReg + category) > paramRangeEnd)); 579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Analyze each instruction and find out all the local variable assignments 583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and move-result-pseudo/invoke-range instrucitons. 584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void analyzeInstructions() { 586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ssaMeth.forEachInsn(new SsaInsn.Visitor() { 587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void visitMoveInsn(NormalSsaInsn insn) { 589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project processInsn(insn); 590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void visitPhiInsn(PhiInsn insn) { 594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project processInsn(insn); 595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void visitNonMoveInsn(NormalSsaInsn insn) { 599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project processInsn(insn); 600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This method collects three types of instructions: 60464986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * 605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1) Adds a local variable assignment to the 60699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code localVariables} map. 607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 2) Add move-result-pseudo to the 60899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code moveResultPseudoInsns} list. 609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 3) Add invoke-range to the 61099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code invokeRangeInsns} list. 611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 61299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param insn {@code non-null;} insn that may represent a 61399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * local variable assignment 614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void processInsn(SsaInsn insn) { 616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec assignment; 617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assignment = insn.getLocalAssignment(); 618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (assignment != null) { 620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LocalItem local = assignment.getLocalItem(); 621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 62299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project ArrayList<RegisterSpec> regList 62399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project = localVariables.get(local); 624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (regList == null) { 626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regList = new ArrayList<RegisterSpec>(); 627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project localVariables.put(local, regList); 628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project regList.add(assignment); 631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (insn instanceof NormalSsaInsn) { 634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (insn.getOpcode().getOpcode() == 635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegOps.MOVE_RESULT_PSEUDO) { 636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project moveResultPseudoInsns.add((NormalSsaInsn) insn); 637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (Optimizer.getAdvice().requiresSourcesInOrder( 638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insn.getOriginalRopInsn().getOpcode(), 639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project insn.getSources())) { 640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project invokeRangeInsns.add((NormalSsaInsn) insn); 641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 6426ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao } else if (insn instanceof PhiInsn) { 6436ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao phiInsns.add((PhiInsn) insn); 644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project }); 648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 65164986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * Adds a mapping from an SSA register to a rop register. 65299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@link #canMapReg} should have already been called. 653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 65499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param ssaSpec {@code non-null;} SSA register to map from 65564986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * @param ropReg {@code >=0;} rop register to map to 656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void addMapping(RegisterSpec ssaSpec, int ropReg) { 658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ssaReg = ssaSpec.getReg(); 659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 66064986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein // An assertion. 661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ssaRegsMapped.get(ssaReg) || !canMapReg(ssaSpec, ropReg)) { 662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new RuntimeException( 663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "attempt to add invalid register mapping"); 664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (DEBUG) { 667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project System.out.printf("Add mapping s%d -> v%d c:%d\n", 66899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project ssaSpec.getReg(), ropReg, ssaSpec.getCategory()); 669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int category = ssaSpec.getCategory(); 672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mapper.addMapping(ssaSpec.getReg(), ropReg, category); 673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ssaRegsMapped.set(ssaReg); 674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project usedRopRegs.set(ropReg, ropReg + category); 675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Maps the source registers of the specified instruction such that they 68064986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * will fall in a contiguous range in rop form. Moves are inserted as 681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * necessary to allow the range to be allocated. 682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 68399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param insn {@code non-null;} insn whos sources to process 684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void adjustAndMapSourceRangeRange(NormalSsaInsn insn) { 68699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project int newRegStart = findRangeAndAdjust(insn); 687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpecList sources = insn.getSources(); 689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int szSources = sources.size(); 690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int nextRopReg = newRegStart; 69199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < szSources; i++) { 693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec source = sources.get(i); 694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int sourceReg = source.getReg(); 695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int category = source.getCategory(); 696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int curRopReg = nextRopReg; 697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nextRopReg += category; 698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ssaRegsMapped.get(sourceReg)) { 700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project LocalItem localItem = getLocalItemForReg(sourceReg); 704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project addMapping(source, curRopReg); 705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (localItem != null) { 707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project markReserved(curRopReg, category); 708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ArrayList<RegisterSpec> similarRegisters 709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project = localVariables.get(localItem); 710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int szSimilar = similarRegisters.size(); 712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 71364986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein /* 71464986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * Try to map all SSA registers also associated with 71564986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * this local. 71664986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein */ 717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int j = 0; j < szSimilar; j++) { 718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec similarSpec = similarRegisters.get(j); 719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int similarReg = similarSpec.getReg(); 720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 72164986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein // Don't map anything that's also a source. 722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (-1 != sources.indexOfRegister(similarReg)) { 723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 72664986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein // Registers left unmapped will get handled later. 727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tryMapReg(similarSpec, curRopReg, category); 728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Find a contiguous rop register range that fits the specified 735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instruction's sources. First, try to center the range around 73664986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * sources that have already been mapped to rop registers. If that fails, 737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * just find a new contiguous range that doesn't interfere. 73864986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * 73999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param insn {@code non-null;} the insn whose sources need to 74099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * fit. Must be last insn in basic block. 74199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code >= 0;} rop register of start of range 742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int findRangeAndAdjust(NormalSsaInsn insn) { 744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpecList sources = insn.getSources(); 745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int szSources = sources.size(); 746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // the category for each source index 747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int categoriesForIndex[] = new int[szSources]; 748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int rangeLength = 0; 749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Compute rangeLength and categoriesForIndex 751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < szSources; i++) { 752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int category = sources.get(i).getCategory(); 753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project categoriesForIndex[i] = category; 754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project rangeLength += categoriesForIndex[i]; 755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 75764986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein // the highest score of fits tried so far 758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int maxScore = Integer.MIN_VALUE; 759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // the high scoring range's start 760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int resultRangeStart = -1; 761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // by source index: set of sources needing moves in high scoring plan 762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project BitSet resultMovesRequired = null; 763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * First, go through each source that's already been mapped. Try 76664986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * to center the range around the rop register this source is mapped 767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to. 768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int rangeStartOffset = 0; 770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < szSources; i++) { 771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ssaCenterReg = sources.get(i).getReg(); 772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (i != 0) { 774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project rangeStartOffset -= categoriesForIndex[i - 1]; 775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!ssaRegsMapped.get(ssaCenterReg)) { 777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int rangeStart = mapper.oldToNew(ssaCenterReg) + rangeStartOffset; 781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (rangeStart < 0 || spansParamRange(rangeStart, rangeLength)) { 783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project BitSet curMovesRequired = new BitSet(szSources); 787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int fitWidth 789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project = fitPlanForRange(rangeStart, insn, categoriesForIndex, 790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project curMovesRequired); 791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fitWidth < 0) { 793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int score = fitWidth - curMovesRequired.cardinality(); 797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (score > maxScore) { 799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project maxScore = score; 800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resultRangeStart = rangeStart; 801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resultMovesRequired = curMovesRequired; 802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fitWidth == rangeLength) { 805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // We can't do any better than this, so stop here 806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If we were unable to find a plan for a fit centered around 812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * an already-mapped source, just try to find a range of 813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * registers we can move the range into. 814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resultRangeStart == -1) { 817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resultMovesRequired = new BitSet(szSources); 818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resultRangeStart = findAnyFittingRange(insn, rangeLength, 820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project categoriesForIndex, resultMovesRequired); 821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 82464986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * Now, insert any moves required. 825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 82741aecd0a6bfea1e9a6713014b2b3d56fec8c552cDan Bornstein for (int i = resultMovesRequired.nextSetBit(0); i >= 0; 82841aecd0a6bfea1e9a6713014b2b3d56fec8c552cDan Bornstein i = resultMovesRequired.nextSetBit(i+1)) { 82941aecd0a6bfea1e9a6713014b2b3d56fec8c552cDan Bornstein insn.changeOneSource(i, insertMoveBefore(insn, sources.get(i))); 830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return resultRangeStart; 833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Finds an unreserved range that will fit the sources of the 837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * specified instruction. Does not bother trying to center the range 838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * around an already-mapped source register; 839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 84099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param insn {@code non-null;} insn to build range for 84164986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * @param rangeLength {@code >=0;} length required in register units 84299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param categoriesForIndex {@code non-null;} indexed by source index; 84364986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * the category for each source 84499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param outMovesRequired {@code non-null;} an output parameter indexed by 845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * source index that will contain the set of sources which need 84664986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * moves inserted 84764986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * @return the rop register that starts the fitting range 848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int findAnyFittingRange(NormalSsaInsn insn, int rangeLength, 850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int[] categoriesForIndex, BitSet outMovesRequired) { 851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int rangeStart = 0; 852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (true) { 853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project rangeStart = findNextUnreservedRopReg(rangeStart, rangeLength); 854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int fitWidth 855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project = fitPlanForRange(rangeStart, insn, 856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project categoriesForIndex, outMovesRequired); 857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fitWidth >= 0) { 859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project rangeStart++; 862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outMovesRequired.clear(); 863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return rangeStart; 865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Attempts to build a plan for fitting a range of sources into rop 869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * registers. 870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 87199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param ropReg {@code >= 0;} rop reg that begins range 87299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param insn {@code non-null;} insn to plan range for 87399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param categoriesForIndex {@code non-null;} indexed by source index; 87464986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * the category for each source 87599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param outMovesRequired {@code non-null;} an output parameter indexed by 876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * source index that will contain the set of sources which need 87764986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * moves inserted 878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the width of the fit that that does not involve added moves or 87964986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * {@code -1} if "no fit possible" 880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int fitPlanForRange(int ropReg, NormalSsaInsn insn, 882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int[] categoriesForIndex, BitSet outMovesRequired) { 883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpecList sources = insn.getSources(); 884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int szSources = sources.size(); 885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int fitWidth = 0; 886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project IntSet liveOut = insn.getBlock().getLiveOutRegs(); 887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpecList liveOutSpecs = ssaSetToSpecs(liveOut); 888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 88964986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein // An SSA reg may only be mapped into a range once. 890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project BitSet seen = new BitSet(ssaMeth.getRegCount()); 891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < szSources ; i++) { 893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec ssaSpec = sources.get(i); 894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ssaReg = ssaSpec.getReg(); 895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int category = categoriesForIndex[i]; 896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (i != 0) { 898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ropReg += categoriesForIndex[i-1]; 899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ssaRegsMapped.get(ssaReg) 902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project && mapper.oldToNew(ssaReg) == ropReg) { 90364986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein // This is a register that is already mapped appropriately. 904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fitWidth += category; 905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (rangeContainsReserved(ropReg, category)) { 906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fitWidth = -1; 907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (!ssaRegsMapped.get(ssaReg) 909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project && canMapReg(ssaSpec, ropReg) 910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project && !seen.get(ssaReg)) { 91164986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein // This is a register that can be mapped appropriately. 912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fitWidth += category; 913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (!mapper.areAnyPinned(liveOutSpecs, ropReg, category) 914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project && !mapper.areAnyPinned(sources, ropReg, category)) { 915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 91664986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * This is a source that can be moved. We can insert a 91764986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * move as long as: 91864986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * 91964986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * * no SSA register pinned to the desired rop reg 92064986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * is live out on the block 921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 92264986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * * no SSA register pinned to desired rop reg is 92364986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * a source of this insn (since this may require 92464986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * overlapping moves, which we can't presently handle) 925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outMovesRequired.set(i); 928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fitWidth = -1; 930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project seen.set(ssaReg); 934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return fitWidth; 936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Converts a bit set of SSA registers into a RegisterSpecList containing 940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the definition specs of all the registers. 941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 94299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param ssaSet {@code non-null;} set of SSA registers 943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return list of RegisterSpecs as noted above 944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpecList ssaSetToSpecs(IntSet ssaSet) { 946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpecList result = new RegisterSpecList(ssaSet.elements()); 947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project IntIterator iter = ssaSet.iterator(); 949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i = 0; 951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (iter.hasNext()) { 952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.set(i++, getDefinitionSpecForSsaReg(iter.next())); 953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 95464986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein 955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 95964986d4f1b50a5f3a12e05eb179ae9ad555814e7Dan Bornstein * Gets a local item associated with an ssa register, if one exists. 960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 96199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param ssaReg {@code >= 0;} SSA register 96299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code null-ok;} associated local item or null 963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private LocalItem getLocalItemForReg(int ssaReg) { 96541aecd0a6bfea1e9a6713014b2b3d56fec8c552cDan Bornstein for (Map.Entry<LocalItem, ArrayList<RegisterSpec>> entry : 96641aecd0a6bfea1e9a6713014b2b3d56fec8c552cDan Bornstein localVariables.entrySet()) { 96799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project for (RegisterSpec spec : entry.getValue()) { 968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (spec.getReg() == ssaReg) { 969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return entry.getKey(); 970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 9766ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao 9776ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao /** 9786ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao * Attempts to map the sources and result of a phi to a common register. 9791acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao * Will try existing mappings first, from most to least common. If none 9801acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao * of the registers have mappings yet, a new mapping is created. 9816ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao */ 9826ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao private void processPhiInsn(PhiInsn insn) { 9836ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao RegisterSpec result = insn.getResult(); 9846ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao int resultReg = result.getReg(); 9856ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao int category = result.getCategory(); 9861acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao 9871acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao RegisterSpecList sources = insn.getSources(); 9881acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao int sourcesSize = sources.size(); 9891acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao 9901acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao // List of phi sources / result that need mapping 9916ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao ArrayList<RegisterSpec> ssaRegs = new ArrayList<RegisterSpec>(); 9926ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao 9931acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao // Track how many times a particular mapping is found 9941acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao Multiset mapSet = new Multiset(sourcesSize + 1); 9951acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao 9961acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao /* 9971acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao * If the result of the phi has an existing mapping, get it. 9981acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao * Otherwise, add it to the list of regs that need mapping. 9991acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao */ 10006ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao if (ssaRegsMapped.get(resultReg)) { 10011acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao mapSet.add(mapper.oldToNew(resultReg)); 10021acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao } else { 10031acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao ssaRegs.add(result); 10046ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao } 10056ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao 10061acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao for (int i = 0; i < sourcesSize; i++) { 10076ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao RegisterSpec source = sources.get(i); 10086ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao int sourceReg = source.getReg(); 10096ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao 10101acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao /* 10111acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao * If a source of the phi has an existing mapping, get it. 10121acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao * Otherwise, add it to the list of regs that need mapping. 10131acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao */ 10146ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao if (ssaRegsMapped.get(sourceReg)) { 10151acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao mapSet.add(mapper.oldToNew(sourceReg)); 10161acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao } else { 10171acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao ssaRegs.add(source); 10181acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao } 10191acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao } 10201acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao 10211acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao // Try all existing mappings, with the most common ones first 10221acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao for (int i = 0; i < mapSet.getSize(); i++) { 10231acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao int maxReg = mapSet.getAndRemoveHighestCount(); 10241acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao tryMapRegs(ssaRegs, maxReg, category, false); 10251acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao } 10261acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao 10271acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao // Map any remaining unmapped regs with whatever fits 10281acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao int mapReg = findNextUnreservedRopReg(0, category); 10291acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao while (!tryMapRegs(ssaRegs, mapReg, category, false)) { 10301acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao mapReg = findNextUnreservedRopReg(mapReg + 1, category); 10311acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao } 10321acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao } 10336ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao 10341acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao // A set that tracks how often elements are added to it. 10351acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao private static class Multiset { 10361acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao private final int[] reg; 10371acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao private final int[] count; 10381acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao private int size; 10391acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao 10401acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao /** 10411acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao * Constructs an instance. 10421acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao * 10431acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao * @param maxSize the maximum distinct elements the set may have 10441acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao */ 10451acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao public Multiset(int maxSize) { 10461acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao reg = new int[maxSize]; 10471acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao count = new int[maxSize]; 10481acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao size = 0; 10491acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao } 10501acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao 10511acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao /** 10521acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao * Adds an element to the set. 10531acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao * 10541acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao * @param element element to add 10551acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao */ 10561acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao public void add(int element) { 10571acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao for (int i = 0; i < size; i++) { 10581acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao if (reg[i] == element) { 10591acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao count[i]++; 10606ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao return; 10616ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao } 10621acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao } 10631acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao 10641acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao reg[size] = element; 10651acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao count[size] = 1; 10661acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao size++; 10671acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao } 10686ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao 10691acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao /** 10701acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao * Searches the set for the element that has been added the most. 10711acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao * In the case of a tie, the element that was added first is returned. 10721acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao * Then, it clears the count on that element. The size of the set 10731acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao * remains unchanged. 10741acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao * 10751acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao * @return element with the highest count 10761acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao */ 10771acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao public int getAndRemoveHighestCount() { 10781acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao int maxIndex = -1; 10791acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao int maxReg = -1; 10801acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao int maxCount = 0; 10811acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao 10821acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao for (int i = 0; i < size; i++) { 10831acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao if (maxCount < count[i]) { 10841acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao maxIndex = i; 10851acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao maxReg = reg[i]; 10861acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao maxCount = count[i]; 10871acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao } 10886ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao } 10891acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao 10901acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao count[maxIndex] = 0; 10911acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao return maxReg; 10926ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao } 10936ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao 10941acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao /** 10951acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao * Gets the number of distinct elements in the set. 10961acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao * 10971acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao * @return size of the set 10981acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao */ 10991acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao public int getSize() { 11001acb3f560b45df68d5acdcb2759de1f78ef5da7cjeffhao return size; 11016ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao } 11026ca2505711b24a91385c6bf46dbef5c404dcf65fjeffhao } 1103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1104