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 19fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport com.android.dx.rop.code.Insn; 20fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport com.android.dx.rop.code.LocalItem; 21fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport com.android.dx.rop.code.RegisterSpec; 22fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport com.android.dx.rop.code.RegisterSpecList; 23fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport com.android.dx.rop.code.Rop; 24fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport com.android.dx.rop.code.SourcePosition; 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.Type; 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.TypeBearer; 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.Hex; 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.ArrayList; 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.List; 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * A Phi instruction (magical post-control-flow-merge) instruction 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in SSA form. Will be converted to moves in predecessor blocks before 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * conversion back to ROP form. 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class PhiInsn extends SsaInsn { 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 3899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * result register. The original result register of the phi insn 3999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * is needed during the renaming process after the new result 4099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * register has already been chosen. 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 4299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project private final int ropResultReg; 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 4599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code non-null;} operands of the instruction; built up by 4699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@link #addPhiOperand} 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 4899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project private final ArrayList<Operand> operands = new ArrayList<Operand>(); 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code null-ok;} source registers; constructed lazily */ 5199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project private RegisterSpecList sources; 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs a new phi insn with no operands. 55de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param resultReg the result reg for this phi insn 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param block block containing this insn. 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public PhiInsn(RegisterSpec resultReg, SsaBasicBlock block) { 6099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project super(resultReg, block); 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ropResultReg = resultReg.getReg(); 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Makes a phi insn with a void result type. 66de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param resultReg the result register for this phi insn. 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param block block containing this insn. 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 7099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public PhiInsn(final int resultReg, final SsaBasicBlock block) { 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 7299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * The result type here is bogus: The type depends on the 7399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * operand and will be derived later. 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 7599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project super(RegisterSpec.make(resultReg, Type.VOID), block); 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ropResultReg = resultReg; 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 7999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@inheritDoc} */ 80b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao @Override 8199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public PhiInsn clone() { 8299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project throw new UnsupportedOperationException("can't clone phi"); 8399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project } 8499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Updates the TypeBearers of all the sources (phi operands) to be 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the current TypeBearer of the register-defining instruction's result. 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This is used during phi-type resolution.<p> 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Note that local association of operands are preserved in this step. 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param ssaMeth method that contains this insn 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 9499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public void updateSourcesToDefinitions(SsaMethod ssaMeth) { 9599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project for (Operand o : operands) { 96de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro RegisterSpec def 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project = ssaMeth.getDefinitionForRegister( 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project o.regSpec.getReg()).getResult(); 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project o.regSpec = o.regSpec.withType(def.getType()); 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources = null; 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Changes the result type. Used during phi type resolution 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param type {@code non-null;} new TypeBearer 11099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param local {@code null-ok;} new local info, if available 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 11299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public void changeResultType(TypeBearer type, LocalItem local) { 11399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project setResult(RegisterSpec.makeLocalOptional( 11499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project getResult().getReg(), type, local)); 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 11899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Gets the original rop-form result reg. This is useful during renaming. 119de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 12099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return the original rop-form result reg 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 12299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public int getRopResultReg() { 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ropResultReg; 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 12799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Adds an operand to this phi instruction. 128de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param registerSpec register spec, including type and reg of operand 13099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param predBlock predecessor block to be associated with this operand 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void addPhiOperand(RegisterSpec registerSpec, 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project SsaBasicBlock predBlock) { 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project operands.add(new Operand(registerSpec, predBlock.getIndex(), 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project predBlock.getRopLabel())); 136de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 13799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project // Un-cache sources, in case someone has already called getSources(). 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources = null; 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 142b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao * Removes all operand uses of a register from this phi instruction. 143b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao * 144b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao * @param registerSpec register spec, including type and reg of operand 145b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao */ 146b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao public void removePhiRegister(RegisterSpec registerSpec) { 147b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao ArrayList<Operand> operandsToRemove = new ArrayList<Operand>(); 148b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao for (Operand o : operands) { 149b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao if (o.regSpec.getReg() == registerSpec.getReg()) { 150b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao operandsToRemove.add(o); 151b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao } 152b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao } 153b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao 154b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao operands.removeAll(operandsToRemove); 155b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao 156b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao // Un-cache sources, in case someone has already called getSources(). 157b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao sources = null; 158b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao } 159b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao 160b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao /** 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the index of the pred block associated with the RegisterSpec 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * at the particular getSources() index. 163de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param sourcesIndex index of source in getSources() 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return block index 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public int predBlockIndexForSourcesIndex(int sourcesIndex) { 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return operands.get(sourcesIndex).blockIndex; 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@inheritDoc} 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 17499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Always returns null for {@code PhiInsn}s. 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Rop getOpcode() { 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@inheritDoc} 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 18499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Always returns null for {@code PhiInsn}s. 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Insn getOriginalRopInsn() { 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@inheritDoc} 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 19499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Always returns false for {@code PhiInsn}s. 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean canThrow() { 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets sources. Constructed lazily from phi operand data structures and 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * then cached. 204de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 20599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} sources list 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 207b75d1ca580c6a6c7ebdc813dff2855205063fc46jeffhao @Override 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public RegisterSpecList getSources() { 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (sources != null) { 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return sources; 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (operands.size() == 0) { 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // How'd this happen? A phi insn with no operand? 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return RegisterSpecList.EMPTY; 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int szSources = operands.size(); 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources = new RegisterSpecList(szSources); 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < szSources; i++) { 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Operand o = operands.get(i); 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources.set(i, o.regSpec); 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources.setImmutable(); 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return sources; 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean isRegASource(int reg) { 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Avoid creating a sources list in case it has not already been 23699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * created. 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 23999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project for (Operand o : operands) { 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (o.regSpec.getReg() == reg) { 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return true if all operands use the same register 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public boolean areAllOperandsEqual() { 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (operands.size() == 0 ) { 25399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project // This should never happen. 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int firstReg = operands.get(0).regSpec.getReg(); 25899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project for (Operand o : operands) { 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (firstReg != o.regSpec.getReg()) { 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final void mapSourceRegisters(RegisterMapper mapper) { 27099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project for (Operand o : operands) { 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RegisterSpec old = o.regSpec; 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project o.regSpec = mapper.map(old); 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (old != o.regSpec) { 27499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project getBlock().getParent().onSourceChanged(this, old, o.regSpec); 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sources = null; 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 28199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Always throws an exeption, since a phi insn may not be 28299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * converted back to rop form. 283de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return always throws exception 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Insn toRopInsn() { 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalArgumentException( 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "Cannot convert phi insns to rop form"); 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the list of predecessor blocks associated with all operands 29499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * that have {@code reg} as an operand register. 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param reg register to look up 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param ssaMeth method we're operating on 29899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return list of predecessor blocks, empty if none 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 30099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public List<SsaBasicBlock> predBlocksForReg(int reg, SsaMethod ssaMeth) { 30199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project ArrayList<SsaBasicBlock> ret = new ArrayList<SsaBasicBlock>(); 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 30399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project for (Operand o : operands) { 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (o.regSpec.getReg() == reg) { 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ret.add(ssaMeth.getBlocks().get(o.blockIndex)); 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ret; 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 31499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public boolean isPhiOrMove() { 315de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro return true; 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 31999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project @Override 32099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public boolean hasSideEffect() { 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return Optimizer.getPreserveLocals() && getLocalAssignment() != null; 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void accept(SsaInsn.Visitor v) { 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project v.visitPhiInsn(this); 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 33099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@inheritDoc} */ 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String toHuman() { 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return toHumanWithInline(null); 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 33699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Returns human-readable string for listing dumps. This method 33799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * allows sub-classes to specify extra text. 338de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 33999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param extra {@code null-ok;} the argument to print after the opcode 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return human-readable string for listing dumps 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final String toHumanWithInline(String extra) { 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringBuffer sb = new StringBuffer(80); 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(SourcePosition.NO_INFO); 346de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro sb.append(": phi"); 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (extra != null) { 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append("("); 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(extra); 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(")"); 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 35499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project RegisterSpec result = getResult(); 355de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == null) { 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(" ."); 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(" "); 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(result.toHuman()); 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(" <-"); 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int sz = getSources().size(); 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (sz == 0) { 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(" ."); 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < sz; i++) { 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(" "); 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sb.append(sources.get(i).toHuman() 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project + "[b=" 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project + Hex.u2(operands.get(i).ropLabel) + "]"); 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return sb.toString(); 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 37999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 38099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** 38199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * A single phi operand, consiting of source register and block index 38299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * for move. 38399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */ 38499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project private static class Operand { 38599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public RegisterSpec regSpec; 38699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public final int blockIndex; 38799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public final int ropLabel; // only used for debugging 38899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 3894b4413ab3d8de5805276cfcde3d7f535d9f64e85Dan Bornstein public Operand(RegisterSpec regSpec, int blockIndex, int ropLabel) { 39099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project this.regSpec = regSpec; 39199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project this.blockIndex = blockIndex; 39299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project this.ropLabel = ropLabel; 39399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project } 39499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project } 39599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project 39699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** 39799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Visitor interface for instances of this (outer) class. 39899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project */ 39999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public static interface Visitor { 40099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project public void visitPhiInsn(PhiInsn insn); 40199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project } 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 403