PhiInsn.java revision de75089fb7216d19e9c22cce4dc62a49513477d3
1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.android.dx.ssa; 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.*; 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.Type; 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.TypeBearer; 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.Hex; 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.ArrayList; 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.List; 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * A Phi instruction (magical post-control-flow-merge) instruction 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in SSA form. Will be converted to moves in predecessor blocks before 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * conversion back to ROP form. 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class PhiInsn extends SsaInsn { 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 3499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * result register. The original result register of the phi insn 3599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * is needed during the renaming process after the new result 3699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * register has already been chosen. 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project private final int ropResultReg; 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 4199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code non-null;} operands of the instruction; built up by 4299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@link #addPhiOperand} 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 4499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project private final ArrayList<Operand> operands = new ArrayList<Operand>(); 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code null-ok;} source registers; constructed lazily */ 4799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project private RegisterSpecList sources; 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs a new phi insn with no operands. 51de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param resultReg the result reg for this phi insn 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param block block containing this insn. 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public PhiInsn(RegisterSpec resultReg, SsaBasicBlock block) { 5699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project super(resultReg, block); 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ropResultReg = resultReg.getReg(); 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Makes a phi insn with a void result type. 62de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param resultReg the result register for this phi insn. 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param block block containing this insn. 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 6699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public PhiInsn(final int resultReg, final SsaBasicBlock block) { 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 6899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * The result type here is bogus: The type depends on the 6999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * operand and will be derived later. 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 7199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project super(RegisterSpec.make(resultReg, Type.VOID), block); 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ropResultReg = resultReg; 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 7599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@inheritDoc} */ 7699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public PhiInsn clone() { 7799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project throw new UnsupportedOperationException("can't clone phi"); 7899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project } 7999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Updates the TypeBearers of all the sources (phi operands) to be 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the current TypeBearer of the register-defining instruction's result. 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This is used during phi-type resolution.<p> 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Note that local association of operands are preserved in this step. 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param ssaMeth method that contains this insn 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 8999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public void updateSourcesToDefinitions(SsaMethod ssaMeth) { 9099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project for (Operand o : operands) { 91de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro RegisterSpec def 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project = ssaMeth.getDefinitionForRegister( 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project o.regSpec.getReg()).getResult(); 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project o.regSpec = o.regSpec.withType(def.getType()); 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources = null; 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Changes the result type. Used during phi type resolution 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param type {@code non-null;} new TypeBearer 10599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param local {@code null-ok;} new local info, if available 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 10799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public void changeResultType(TypeBearer type, LocalItem local) { 10899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project setResult(RegisterSpec.makeLocalOptional( 10999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project getResult().getReg(), type, local)); 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 11399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Gets the original rop-form result reg. This is useful during renaming. 114de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 11599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return the original rop-form result reg 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 11799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public int getRopResultReg() { 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ropResultReg; 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 12299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Adds an operand to this phi instruction. 123de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param registerSpec register spec, including type and reg of operand 12599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param predBlock predecessor block to be associated with this operand 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void addPhiOperand(RegisterSpec registerSpec, 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SsaBasicBlock predBlock) { 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project operands.add(new Operand(registerSpec, predBlock.getIndex(), 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project predBlock.getRopLabel())); 131de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 13299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project // Un-cache sources, in case someone has already called getSources(). 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources = null; 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the index of the pred block associated with the RegisterSpec 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * at the particular getSources() index. 139de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param sourcesIndex index of source in getSources() 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return block index 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int predBlockIndexForSourcesIndex(int sourcesIndex) { 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return operands.get(sourcesIndex).blockIndex; 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@inheritDoc} 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 15099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Always returns null for {@code PhiInsn}s. 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Rop getOpcode() { 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@inheritDoc} 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 16099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Always returns null for {@code PhiInsn}s. 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Insn getOriginalRopInsn() { 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@inheritDoc} 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 17099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Always returns false for {@code PhiInsn}s. 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean canThrow() { 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets sources. Constructed lazily from phi operand data structures and 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * then cached. 180de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 18199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} sources list 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public RegisterSpecList getSources() { 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (sources != null) { 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return sources; 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (operands.size() == 0) { 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // How'd this happen? A phi insn with no operand? 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegisterSpecList.EMPTY; 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int szSources = operands.size(); 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources = new RegisterSpecList(szSources); 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < szSources; i++) { 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Operand o = operands.get(i); 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources.set(i, o.regSpec); 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources.setImmutable(); 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return sources; 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean isRegASource(int reg) { 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Avoid creating a sources list in case it has not already been 21199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * created. 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 21499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project for (Operand o : operands) { 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (o.regSpec.getReg() == reg) { 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return true if all operands use the same register 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean areAllOperandsEqual() { 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (operands.size() == 0 ) { 22899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project // This should never happen. 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int firstReg = operands.get(0).regSpec.getReg(); 23399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project for (Operand o : operands) { 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (firstReg != o.regSpec.getReg()) { 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final void mapSourceRegisters(RegisterMapper mapper) { 24599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project for (Operand o : operands) { 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec old = o.regSpec; 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project o.regSpec = mapper.map(old); 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (old != o.regSpec) { 24999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project getBlock().getParent().onSourceChanged(this, old, o.regSpec); 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources = null; 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 25699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Always throws an exeption, since a phi insn may not be 25799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * converted back to rop form. 258de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return always throws exception 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Insn toRopInsn() { 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException( 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "Cannot convert phi insns to rop form"); 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the list of predecessor blocks associated with all operands 26999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * that have {@code reg} as an operand register. 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param reg register to look up 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param ssaMeth method we're operating on 27399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return list of predecessor blocks, empty if none 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 27599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public List<SsaBasicBlock> predBlocksForReg(int reg, SsaMethod ssaMeth) { 27699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project ArrayList<SsaBasicBlock> ret = new ArrayList<SsaBasicBlock>(); 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 27899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project for (Operand o : operands) { 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (o.regSpec.getReg() == reg) { 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ret.add(ssaMeth.getBlocks().get(o.blockIndex)); 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ret; 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 28999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public boolean isPhiOrMove() { 290de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro return true; 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 29499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project @Override 29599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public boolean hasSideEffect() { 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return Optimizer.getPreserveLocals() && getLocalAssignment() != null; 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void accept(SsaInsn.Visitor v) { 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project v.visitPhiInsn(this); 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 30599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@inheritDoc} */ 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String toHuman() { 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return toHumanWithInline(null); 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 31199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Returns human-readable string for listing dumps. This method 31299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * allows sub-classes to specify extra text. 313de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 31499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param extra {@code null-ok;} the argument to print after the opcode 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return human-readable string for listing dumps 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final String toHumanWithInline(String extra) { 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringBuffer sb = new StringBuffer(80); 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(SourcePosition.NO_INFO); 321de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro sb.append(": phi"); 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (extra != null) { 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append("("); 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(extra); 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(")"); 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 32999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project RegisterSpec result = getResult(); 330de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == null) { 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(" ."); 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(" "); 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(result.toHuman()); 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(" <-"); 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int sz = getSources().size(); 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (sz == 0) { 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(" ."); 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < sz; i++) { 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(" "); 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(sources.get(i).toHuman() 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project + "[b=" 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project + Hex.u2(operands.get(i).ropLabel) + "]"); 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return sb.toString(); 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 35499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 35599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** 35699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * A single phi operand, consiting of source register and block index 35799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * for move. 35899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */ 35999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project private static class Operand { 36099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public RegisterSpec regSpec; 36199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public final int blockIndex; 36299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public final int ropLabel; // only used for debugging 36399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 3644b4413ab3d8de5805276cfcde3d7f535d9f64e85Dan Bornstein public Operand(RegisterSpec regSpec, int blockIndex, int ropLabel) { 36599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project this.regSpec = regSpec; 36699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project this.blockIndex = blockIndex; 36799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project this.ropLabel = ropLabel; 36899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project } 36999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project } 37099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 37199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** 37299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Visitor interface for instances of this (outer) class. 37399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */ 37499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public static interface Visitor { 37599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public void visitPhiInsn(PhiInsn insn); 37699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project } 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 378