PhiInsn.java revision b75d1ca580c6a6c7ebdc813dff2855205063fc46
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} */ 76b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao @Override 7799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public PhiInsn clone() { 7899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project throw new UnsupportedOperationException("can't clone phi"); 7999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project } 8099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Updates the TypeBearers of all the sources (phi operands) to be 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the current TypeBearer of the register-defining instruction's result. 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This is used during phi-type resolution.<p> 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Note that local association of operands are preserved in this step. 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param ssaMeth method that contains this insn 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 9099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public void updateSourcesToDefinitions(SsaMethod ssaMeth) { 9199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project for (Operand o : operands) { 92de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro RegisterSpec def 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project = ssaMeth.getDefinitionForRegister( 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project o.regSpec.getReg()).getResult(); 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project o.regSpec = o.regSpec.withType(def.getType()); 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources = null; 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Changes the result type. Used during phi type resolution 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param type {@code non-null;} new TypeBearer 10699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param local {@code null-ok;} new local info, if available 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 10899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public void changeResultType(TypeBearer type, LocalItem local) { 10999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project setResult(RegisterSpec.makeLocalOptional( 11099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project getResult().getReg(), type, local)); 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 11499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Gets the original rop-form result reg. This is useful during renaming. 115de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 11699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return the original rop-form result reg 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 11899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public int getRopResultReg() { 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ropResultReg; 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 12399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Adds an operand to this phi instruction. 124de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param registerSpec register spec, including type and reg of operand 12699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param predBlock predecessor block to be associated with this operand 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void addPhiOperand(RegisterSpec registerSpec, 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SsaBasicBlock predBlock) { 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project operands.add(new Operand(registerSpec, predBlock.getIndex(), 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project predBlock.getRopLabel())); 132de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 13399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project // Un-cache sources, in case someone has already called getSources(). 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources = null; 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 138b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao * Removes all operand uses of a register from this phi instruction. 139b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao * 140b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao * @param registerSpec register spec, including type and reg of operand 141b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao */ 142b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao public void removePhiRegister(RegisterSpec registerSpec) { 143b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao ArrayList<Operand> operandsToRemove = new ArrayList<Operand>(); 144b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao for (Operand o : operands) { 145b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao if (o.regSpec.getReg() == registerSpec.getReg()) { 146b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao operandsToRemove.add(o); 147b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao } 148b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao } 149b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao 150b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao operands.removeAll(operandsToRemove); 151b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao 152b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao // Un-cache sources, in case someone has already called getSources(). 153b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao sources = null; 154b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao } 155b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao 156b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao /** 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the index of the pred block associated with the RegisterSpec 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * at the particular getSources() index. 159de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param sourcesIndex index of source in getSources() 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return block index 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int predBlockIndexForSourcesIndex(int sourcesIndex) { 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return operands.get(sourcesIndex).blockIndex; 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 null for {@code PhiInsn}s. 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Rop getOpcode() { 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@inheritDoc} 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 18099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Always returns null for {@code PhiInsn}s. 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Insn getOriginalRopInsn() { 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@inheritDoc} 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 19099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Always returns false for {@code PhiInsn}s. 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean canThrow() { 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets sources. Constructed lazily from phi operand data structures and 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * then cached. 200de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 20199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} sources list 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 203b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao @Override 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public RegisterSpecList getSources() { 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (sources != null) { 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return sources; 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (operands.size() == 0) { 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // How'd this happen? A phi insn with no operand? 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegisterSpecList.EMPTY; 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int szSources = operands.size(); 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources = new RegisterSpecList(szSources); 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < szSources; i++) { 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Operand o = operands.get(i); 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources.set(i, o.regSpec); 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources.setImmutable(); 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return sources; 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean isRegASource(int reg) { 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Avoid creating a sources list in case it has not already been 23299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * created. 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 23599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project for (Operand o : operands) { 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (o.regSpec.getReg() == reg) { 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return true if all operands use the same register 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean areAllOperandsEqual() { 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (operands.size() == 0 ) { 24999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project // This should never happen. 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int firstReg = operands.get(0).regSpec.getReg(); 25499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project for (Operand o : operands) { 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (firstReg != o.regSpec.getReg()) { 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final void mapSourceRegisters(RegisterMapper mapper) { 26699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project for (Operand o : operands) { 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec old = o.regSpec; 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project o.regSpec = mapper.map(old); 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (old != o.regSpec) { 27099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project getBlock().getParent().onSourceChanged(this, old, o.regSpec); 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources = null; 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 27799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Always throws an exeption, since a phi insn may not be 27899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * converted back to rop form. 279de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return always throws exception 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Insn toRopInsn() { 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException( 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "Cannot convert phi insns to rop form"); 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the list of predecessor blocks associated with all operands 29099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * that have {@code reg} as an operand register. 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param reg register to look up 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param ssaMeth method we're operating on 29499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return list of predecessor blocks, empty if none 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 29699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public List<SsaBasicBlock> predBlocksForReg(int reg, SsaMethod ssaMeth) { 29799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project ArrayList<SsaBasicBlock> ret = new ArrayList<SsaBasicBlock>(); 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 29999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project for (Operand o : operands) { 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (o.regSpec.getReg() == reg) { 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ret.add(ssaMeth.getBlocks().get(o.blockIndex)); 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ret; 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 31099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public boolean isPhiOrMove() { 311de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro return true; 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 31599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project @Override 31699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public boolean hasSideEffect() { 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return Optimizer.getPreserveLocals() && getLocalAssignment() != null; 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void accept(SsaInsn.Visitor v) { 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project v.visitPhiInsn(this); 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 32699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@inheritDoc} */ 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String toHuman() { 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return toHumanWithInline(null); 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 33299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Returns human-readable string for listing dumps. This method 33399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * allows sub-classes to specify extra text. 334de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 33599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param extra {@code null-ok;} the argument to print after the opcode 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return human-readable string for listing dumps 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final String toHumanWithInline(String extra) { 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringBuffer sb = new StringBuffer(80); 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(SourcePosition.NO_INFO); 342de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro sb.append(": phi"); 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (extra != null) { 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append("("); 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(extra); 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(")"); 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 35099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project RegisterSpec result = getResult(); 351de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == null) { 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(" ."); 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(" "); 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(result.toHuman()); 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(" <-"); 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int sz = getSources().size(); 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (sz == 0) { 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(" ."); 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < sz; i++) { 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(" "); 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(sources.get(i).toHuman() 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project + "[b=" 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project + Hex.u2(operands.get(i).ropLabel) + "]"); 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return sb.toString(); 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 37599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 37699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** 37799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * A single phi operand, consiting of source register and block index 37899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * for move. 37999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */ 38099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project private static class Operand { 38199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public RegisterSpec regSpec; 38299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public final int blockIndex; 38399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public final int ropLabel; // only used for debugging 38499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 3854b4413ab3d8de5805276cfcde3d7f535d9f64e85Dan Bornstein public Operand(RegisterSpec regSpec, int blockIndex, int ropLabel) { 38699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project this.regSpec = regSpec; 38799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project this.blockIndex = blockIndex; 38899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project this.ropLabel = ropLabel; 38999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project } 39099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project } 39199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 39299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** 39399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Visitor interface for instances of this (outer) class. 39499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */ 39599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public static interface Visitor { 39699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public void visitPhiInsn(PhiInsn insn); 39799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project } 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 399