1579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/* 2579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Copyright (C) 2007 The Android Open Source Project 3579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 4579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License"); 5579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * you may not use this file except in compliance with the License. 6579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * You may obtain a copy of the License at 7579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 8579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 9579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 10579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Unless required by applicable law or agreed to in writing, software 11579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 12579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * See the License for the specific language governing permissions and 14579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * limitations under the License. 15579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 16579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 17579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpackage com.android.dx.ssa; 18579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 19579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.code.CstInsn; 20579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.code.Insn; 21579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.code.PlainInsn; 22579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.code.RegOps; 23579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.code.RegisterSpecList; 24579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.code.Rop; 25579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.code.RegisterSpec; 26579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.code.Rops; 27579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.cst.Constant; 28579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.cst.CstInteger; 29579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.cst.TypedConstant; 30579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.type.TypeBearer; 31579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.type.Type; 32579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 33579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.util.ArrayList; 34579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.util.BitSet; 35579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 36579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/** 37579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * A small variant of Wegman and Zadeck's Sparse Conditional Constant 38579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Propagation algorithm. 39579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 40579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpublic class SCCP { 41579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** Lattice values */ 42579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private static final int TOP = 0; 43579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private static final int CONSTANT = 1; 44579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private static final int VARYING = 2; 45579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** method we're processing */ 46579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private SsaMethod ssaMeth; 47579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** ssaMeth.getRegCount() */ 48579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private int regCount; 49579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** Lattice values for each SSA register */ 50579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private int[] latticeValues; 51579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** For those registers that are constant, this is the constant value */ 52579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private Constant[] latticeConstants; 53579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** Worklist of basic blocks to be processed */ 54579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private ArrayList<SsaBasicBlock> cfgWorklist; 55579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** Worklist of executed basic blocks with phis to be processed */ 56579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private ArrayList<SsaBasicBlock> cfgPhiWorklist; 57579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** Bitset containing bits for each block that has been found executable */ 58579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private BitSet executableBlocks; 59579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** Worklist for SSA edges. This is a list of registers to process */ 60579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private ArrayList<SsaInsn> ssaWorklist; 61579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 62579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Worklist for SSA edges that represent varying values. It makes the 63579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * algorithm much faster if you move all values to VARYING as fast as 64579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * possible. 65579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 66579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private ArrayList<SsaInsn> varyingWorklist; 67579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** Worklist of potential branches to convert to gotos */ 68579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private ArrayList<SsaInsn> branchWorklist; 69579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 70579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private SCCP(SsaMethod ssaMeth) { 71579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.ssaMeth = ssaMeth; 72579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.regCount = ssaMeth.getRegCount(); 73579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.latticeValues = new int[this.regCount]; 74579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.latticeConstants = new Constant[this.regCount]; 75579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.cfgWorklist = new ArrayList<SsaBasicBlock>(); 76579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.cfgPhiWorklist = new ArrayList<SsaBasicBlock>(); 77579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.executableBlocks = new BitSet(ssaMeth.getBlocks().size()); 78579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.ssaWorklist = new ArrayList<SsaInsn>(); 79579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.varyingWorklist = new ArrayList<SsaInsn>(); 80579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.branchWorklist = new ArrayList<SsaInsn>(); 81579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (int i = 0; i < this.regCount; i++) { 82579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson latticeValues[i] = TOP; 83579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson latticeConstants[i] = null; 84579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 85579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 86579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 87579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 88579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Performs sparse conditional constant propagation on a method. 89579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param ssaMethod Method to process 90579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 91579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static void process (SsaMethod ssaMethod) { 92579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson new SCCP(ssaMethod).run(); 93579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 94579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 95579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 96579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Adds a SSA basic block to the CFG worklist if it's unexecuted, or 97579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * to the CFG phi worklist if it's already executed. 98579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param ssaBlock Block to add 99579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 100579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private void addBlockToWorklist(SsaBasicBlock ssaBlock) { 101579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (!executableBlocks.get(ssaBlock.getIndex())) { 102579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson cfgWorklist.add(ssaBlock); 103579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson executableBlocks.set(ssaBlock.getIndex()); 104579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else { 105579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson cfgPhiWorklist.add(ssaBlock); 106579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 107579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 108579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 109579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 110579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Adds an SSA register's uses to the SSA worklist. 111579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param reg SSA register 112579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param latticeValue new lattice value for @param reg. 113579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 114579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private void addUsersToWorklist(int reg, int latticeValue) { 115579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (latticeValue == VARYING) { 116579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (SsaInsn insn : ssaMeth.getUseListForRegister(reg)) { 117579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson varyingWorklist.add(insn); 118579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 119579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else { 120579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (SsaInsn insn : ssaMeth.getUseListForRegister(reg)) { 121579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson ssaWorklist.add(insn); 122579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 123579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 124579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 125579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 126579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 127579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Sets a lattice value for a register to value. 128579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param reg SSA register 129579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param value Lattice value 130579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param cst Constant value (may be null) 131579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return true if the lattice value changed. 132579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 133579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private boolean setLatticeValueTo(int reg, int value, Constant cst) { 134579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (value != CONSTANT) { 135579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (latticeValues[reg] != value) { 136579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson latticeValues[reg] = value; 137579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return true; 138579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 139579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return false; 140579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else { 141579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (latticeValues[reg] != value 142579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson || !latticeConstants[reg].equals(cst)) { 143579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson latticeValues[reg] = value; 144579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson latticeConstants[reg] = cst; 145579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return true; 146579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 147579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return false; 148579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 149579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 150579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 151579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 152579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Simulates a PHI node and set the lattice for the result 153579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * to the appropriate value. 154579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Meet values: 155579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * TOP x anything = TOP 156579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * VARYING x anything = VARYING 157579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * CONSTANT x CONSTANT = CONSTANT if equal constants, VARYING otherwise 158579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param insn PHI to simulate. 159579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 160579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private void simulatePhi(PhiInsn insn) { 161579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int phiResultReg = insn.getResult().getReg(); 162579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 163579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (latticeValues[phiResultReg] == VARYING) { 164579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return; 165579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 166579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 167579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpecList sources = insn.getSources(); 168579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int phiResultValue = TOP; 169579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Constant phiConstant = null; 170579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int sourceSize = sources.size(); 171579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 172579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (int i = 0; i < sourceSize; i++) { 173579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int predBlockIndex = insn.predBlockIndexForSourcesIndex(i); 174579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int sourceReg = sources.get(i).getReg(); 175579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int sourceRegValue = latticeValues[sourceReg]; 176579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 177579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (!executableBlocks.get(predBlockIndex)) { 178579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson continue; 179579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 180579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 181579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (sourceRegValue == CONSTANT) { 182579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (phiConstant == null) { 183579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson phiConstant = latticeConstants[sourceReg]; 184579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson phiResultValue = CONSTANT; 185579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else if (!latticeConstants[sourceReg].equals(phiConstant)){ 186579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson phiResultValue = VARYING; 187579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 188579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 189579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else { 190579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson phiResultValue = sourceRegValue; 191579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 192579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 193579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 194579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (setLatticeValueTo(phiResultReg, phiResultValue, phiConstant)) { 195579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson addUsersToWorklist(phiResultReg, phiResultValue); 196579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 197579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 198579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 199579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 200579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Simulate a block and note the results in the lattice. 201579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param block Block to visit 202579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 203579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private void simulateBlock(SsaBasicBlock block) { 204579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (SsaInsn insn : block.getInsns()) { 205579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (insn instanceof PhiInsn) { 206579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson simulatePhi((PhiInsn) insn); 207579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else { 208579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson simulateStmt(insn); 209579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 210579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 211579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 212579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 213579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 214579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Simulate the phis in a block and note the results in the lattice. 215579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param block Block to visit 216579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 217579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private void simulatePhiBlock(SsaBasicBlock block) { 218579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (SsaInsn insn : block.getInsns()) { 219579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (insn instanceof PhiInsn) { 220579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson simulatePhi((PhiInsn) insn); 221579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else { 222579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return; 223579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 224579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 225579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 226579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 227579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private static String latticeValName(int latticeVal) { 228579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson switch (latticeVal) { 229579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case TOP: return "TOP"; 230579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case CONSTANT: return "CONSTANT"; 231579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case VARYING: return "VARYING"; 232579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson default: return "UNKNOWN"; 233579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 234579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 235579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 236579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 237579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Simulates branch insns, if possible. Adds reachable successor blocks 238579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * to the CFG worklists. 239579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param insn branch to simulate 240579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 241579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private void simulateBranch(SsaInsn insn) { 242579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Rop opcode = insn.getOpcode(); 243579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpecList sources = insn.getSources(); 244579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 245579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson boolean constantBranch = false; 246579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson boolean constantSuccessor = false; 247579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 248579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // Check if the insn is a branch with a constant condition 249579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (opcode.getBranchingness() == Rop.BRANCH_IF) { 250579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Constant cA = null; 251579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Constant cB = null; 252579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 253579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpec specA = sources.get(0); 254579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int regA = specA.getReg(); 255579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (!ssaMeth.isRegALocal(specA) && 256579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson latticeValues[regA] == CONSTANT) { 257579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson cA = latticeConstants[regA]; 258579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 259579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 260579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (sources.size() == 2) { 261579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpec specB = sources.get(1); 262579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int regB = specB.getReg(); 263579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (!ssaMeth.isRegALocal(specB) && 264579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson latticeValues[regB] == CONSTANT) { 265579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson cB = latticeConstants[regB]; 266579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 267579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 268579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 269579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // Calculate the result of the condition 270579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (cA != null && sources.size() == 1) { 271579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson switch (((TypedConstant) cA).getBasicType()) { 272579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case Type.BT_INT: 273579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson constantBranch = true; 274579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int vA = ((CstInteger) cA).getValue(); 275579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson switch (opcode.getOpcode()) { 276579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.IF_EQ: 277579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson constantSuccessor = (vA == 0); 278579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 279579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.IF_NE: 280579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson constantSuccessor = (vA != 0); 281579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 282579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.IF_LT: 283579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson constantSuccessor = (vA < 0); 284579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 285579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.IF_GE: 286579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson constantSuccessor = (vA >= 0); 287579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 288579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.IF_LE: 289579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson constantSuccessor = (vA <= 0); 290579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 291579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.IF_GT: 292579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson constantSuccessor = (vA > 0); 293579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 294579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson default: 295579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new RuntimeException("Unexpected op"); 296579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 297579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 298579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson default: 299579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // not yet supported 300579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 301579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else if (cA != null && cB != null) { 302579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson switch (((TypedConstant) cA).getBasicType()) { 303579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case Type.BT_INT: 304579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson constantBranch = true; 305579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int vA = ((CstInteger) cA).getValue(); 306579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int vB = ((CstInteger) cB).getValue(); 307579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson switch (opcode.getOpcode()) { 308579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.IF_EQ: 309579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson constantSuccessor = (vA == vB); 310579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 311579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.IF_NE: 312579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson constantSuccessor = (vA != vB); 313579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 314579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.IF_LT: 315579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson constantSuccessor = (vA < vB); 316579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 317579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.IF_GE: 318579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson constantSuccessor = (vA >= vB); 319579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 320579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.IF_LE: 321579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson constantSuccessor = (vA <= vB); 322579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 323579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.IF_GT: 324579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson constantSuccessor = (vA > vB); 325579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 326579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson default: 327579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new RuntimeException("Unexpected op"); 328579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 329579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 330579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson default: 331579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // not yet supported 332579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 333579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 334579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 335579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 336579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /* 337579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * If condition is constant, add only the target block to the 338579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * worklist. Otherwise, add all successors to the worklist. 339579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 340579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson SsaBasicBlock block = insn.getBlock(); 341579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 342579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (constantBranch) { 343579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int successorBlock; 344579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (constantSuccessor) { 345579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson successorBlock = block.getSuccessorList().get(1); 346579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else { 347579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson successorBlock = block.getSuccessorList().get(0); 348579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 349579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson addBlockToWorklist(ssaMeth.getBlocks().get(successorBlock)); 350579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson branchWorklist.add(insn); 351579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else { 352579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (int i = 0; i < block.getSuccessorList().size(); i++) { 353579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int successorBlock = block.getSuccessorList().get(i); 354579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson addBlockToWorklist(ssaMeth.getBlocks().get(successorBlock)); 355579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 356579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 357579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 358579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 359579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 360579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Simulates math insns, if possible. 361579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 362579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param insn non-null insn to simulate 363579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param resultType basic type of the result 364579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return constant result or null if not simulatable. 365579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 366579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private Constant simulateMath(SsaInsn insn, int resultType) { 367579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Insn ropInsn = insn.getOriginalRopInsn(); 368579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int opcode = insn.getOpcode().getOpcode(); 369579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpecList sources = insn.getSources(); 370579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int regA = sources.get(0).getReg(); 371579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Constant cA; 372579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Constant cB; 373579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 374579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (latticeValues[regA] != CONSTANT) { 375579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson cA = null; 376579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else { 377579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson cA = latticeConstants[regA]; 378579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 379579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 380579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (sources.size() == 1) { 381579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson CstInsn cstInsn = (CstInsn) ropInsn; 382579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson cB = cstInsn.getConstant(); 383579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else { /* sources.size() == 2 */ 384579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int regB = sources.get(1).getReg(); 385579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (latticeValues[regB] != CONSTANT) { 386579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson cB = null; 387579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else { 388579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson cB = latticeConstants[regB]; 389579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 390579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 391579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 392579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (cA == null || cB == null) { 393579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson //TODO handle a constant of 0 with MUL or AND 394579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return null; 395579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 396579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 397579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson switch (resultType) { 398579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case Type.BT_INT: 399579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int vR; 400579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson boolean skip=false; 401579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 402579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int vA = ((CstInteger) cA).getValue(); 403579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int vB = ((CstInteger) cB).getValue(); 404579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 405579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson switch (opcode) { 406579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.ADD: 407579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson vR = vA + vB; 408579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 409579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.SUB: 410579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // 1 source for reverse sub, 2 sources for regular sub 411579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (sources.size() == 1) { 412579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson vR = vB - vA; 413579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else { 414579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson vR = vA - vB; 415579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 416579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 417579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.MUL: 418579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson vR = vA * vB; 419579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 420579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.DIV: 421579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (vB == 0) { 422579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson skip = true; 423579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson vR = 0; // just to hide a warning 424579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else { 425579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson vR = vA / vB; 426579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 427579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 428579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.AND: 429579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson vR = vA & vB; 430579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 431579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.OR: 432579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson vR = vA | vB; 433579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 434579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.XOR: 435579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson vR = vA ^ vB; 436579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 437579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.SHL: 438579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson vR = vA << vB; 439579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 440579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.SHR: 441579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson vR = vA >> vB; 442579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 443579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.USHR: 444579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson vR = vA >>> vB; 445579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 446579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.REM: 447579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (vB == 0) { 448579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson skip = true; 449579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson vR = 0; // just to hide a warning 450579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else { 451579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson vR = vA % vB; 452579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 453579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 454579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson default: 455579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new RuntimeException("Unexpected op"); 456579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 457579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 458579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return skip ? null : CstInteger.make(vR); 459579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 460579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson default: 461579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // not yet supported 462579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return null; 463579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 464579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 465579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 466579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 467579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Simulates a statement and set the result lattice value. 468579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param insn instruction to simulate 469579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 470579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private void simulateStmt(SsaInsn insn) { 471579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Insn ropInsn = insn.getOriginalRopInsn(); 472579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (ropInsn.getOpcode().getBranchingness() != Rop.BRANCH_NONE 473579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson || ropInsn.getOpcode().isCallLike()) { 474579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson simulateBranch(insn); 475579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 476579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 477579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int opcode = insn.getOpcode().getOpcode(); 478579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpec result = insn.getResult(); 479579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 480579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (result == null) { 481579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // Find move-result-pseudo result for int div and int rem 482579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (opcode == RegOps.DIV || opcode == RegOps.REM) { 483579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson SsaBasicBlock succ = insn.getBlock().getPrimarySuccessor(); 484579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson result = succ.getInsns().get(0).getResult(); 485579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else { 486579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return; 487579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 488579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 489579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 490579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int resultReg = result.getReg(); 491579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int resultValue = VARYING; 492579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Constant resultConstant = null; 493579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 494579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson switch (opcode) { 495579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.CONST: { 496579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson CstInsn cstInsn = (CstInsn)ropInsn; 497579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson resultValue = CONSTANT; 498579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson resultConstant = cstInsn.getConstant(); 499579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 500579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 501579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.MOVE: { 502579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (insn.getSources().size() == 1) { 503579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int sourceReg = insn.getSources().get(0).getReg(); 504579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson resultValue = latticeValues[sourceReg]; 505579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson resultConstant = latticeConstants[sourceReg]; 506579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 507579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 508579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 509579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.ADD: 510579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.SUB: 511579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.MUL: 512579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.DIV: 513579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.AND: 514579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.OR: 515579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.XOR: 516579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.SHL: 517579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.SHR: 518579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.USHR: 519579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.REM: { 520579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson resultConstant = simulateMath(insn, result.getBasicType()); 521579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (resultConstant != null) { 522579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson resultValue = CONSTANT; 523579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 524579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 525579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 526579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson case RegOps.MOVE_RESULT_PSEUDO: { 527579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (latticeValues[resultReg] == CONSTANT) { 528579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson resultValue = latticeValues[resultReg]; 529579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson resultConstant = latticeConstants[resultReg]; 530579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 531579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson break; 532579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 533579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // TODO: Handle non-int arithmetic. 534579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // TODO: Eliminate check casts that we can prove the type of. 535579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson default: {} 536579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 537579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (setLatticeValueTo(resultReg, resultValue, resultConstant)) { 538579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson addUsersToWorklist(resultReg, resultValue); 539579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 540579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 541579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 542579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private void run() { 543579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson SsaBasicBlock firstBlock = ssaMeth.getEntryBlock(); 544579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson addBlockToWorklist(firstBlock); 545579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 546579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /* Empty all the worklists by propagating our values */ 547579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson while (!cfgWorklist.isEmpty() 548579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson || !cfgPhiWorklist.isEmpty() 549579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson || !ssaWorklist.isEmpty() 550579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson || !varyingWorklist.isEmpty()) { 551579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson while (!cfgWorklist.isEmpty()) { 552579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int listSize = cfgWorklist.size() - 1; 553579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson SsaBasicBlock block = cfgWorklist.remove(listSize); 554579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson simulateBlock(block); 555579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 556579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 557579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson while (!cfgPhiWorklist.isEmpty()) { 558579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int listSize = cfgPhiWorklist.size() - 1; 559579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson SsaBasicBlock block = cfgPhiWorklist.remove(listSize); 560579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson simulatePhiBlock(block); 561579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 562579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 563579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson while (!varyingWorklist.isEmpty()) { 564579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int listSize = varyingWorklist.size() - 1; 565579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson SsaInsn insn = varyingWorklist.remove(listSize); 566579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 567579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (!executableBlocks.get(insn.getBlock().getIndex())) { 568579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson continue; 569579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 570579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 571579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (insn instanceof PhiInsn) { 572579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson simulatePhi((PhiInsn)insn); 573579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else { 574579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson simulateStmt(insn); 575579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 576579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 577579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson while (!ssaWorklist.isEmpty()) { 578579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int listSize = ssaWorklist.size() - 1; 579579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson SsaInsn insn = ssaWorklist.remove(listSize); 580579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 581579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (!executableBlocks.get(insn.getBlock().getIndex())) { 582579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson continue; 583579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 584579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 585579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (insn instanceof PhiInsn) { 586579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson simulatePhi((PhiInsn)insn); 587579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else { 588579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson simulateStmt(insn); 589579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 590579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 591579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 592579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 593579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson replaceConstants(); 594579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson replaceBranches(); 595579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 596579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 597579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 598579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Replaces TypeBearers in source register specs with constant type 599579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * bearers if possible. These are then referenced in later optimization 600579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * steps. 601579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 602579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private void replaceConstants() { 603579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (int reg = 0; reg < regCount; reg++) { 604579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (latticeValues[reg] != CONSTANT) { 605579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson continue; 606579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 607579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (!(latticeConstants[reg] instanceof TypedConstant)) { 608579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // We can't do much with these 609579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson continue; 610579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 611579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 612579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson SsaInsn defn = ssaMeth.getDefinitionForRegister(reg); 613579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson TypeBearer typeBearer = defn.getResult().getTypeBearer(); 614579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 615579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (typeBearer.isConstant()) { 616579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /* 617579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * The definition was a constant already. 618579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * The uses should be as well. 619579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 620579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson continue; 621579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 622579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 623579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // Update the destination RegisterSpec with the constant value 624579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpec dest = defn.getResult(); 625579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpec newDest 626579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson = dest.withType((TypedConstant)latticeConstants[reg]); 627579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson defn.setResult(newDest); 628579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 629579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /* 630579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Update the sources RegisterSpec's of all non-move uses. 631579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * These will be used in later steps. 632579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 633579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (SsaInsn insn : ssaMeth.getUseListForRegister(reg)) { 634579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (insn.isPhiOrMove()) { 635579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson continue; 636579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 637579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 638579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson NormalSsaInsn nInsn = (NormalSsaInsn) insn; 639579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpecList sources = insn.getSources(); 640579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 641579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int index = sources.indexOfRegister(reg); 642579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 643579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpec spec = sources.get(index); 644579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson RegisterSpec newSpec 645579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson = spec.withType((TypedConstant)latticeConstants[reg]); 646579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 647579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson nInsn.changeOneSource(index, newSpec); 648579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 649579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 650579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 651579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 652579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 653579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Replaces branches that have constant conditions with gotos 654579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 655579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private void replaceBranches() { 656579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (SsaInsn insn : branchWorklist) { 657579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // Find if a successor block is never executed 658579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int oldSuccessor = -1; 659579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson SsaBasicBlock block = insn.getBlock(); 660579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int successorSize = block.getSuccessorList().size(); 661579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (int i = 0; i < successorSize; i++) { 662579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int successorBlock = block.getSuccessorList().get(i); 663579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (!executableBlocks.get(successorBlock)) { 664579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson oldSuccessor = successorBlock; 665579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 666579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 667579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 668579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /* 669579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Prune branches that have already been handled and ones that no 670579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * longer have constant conditions (no nonexecutable successors) 671579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 672579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (successorSize != 2 || oldSuccessor == -1) continue; 673579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 674579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // Replace branch with goto 675579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Insn originalRopInsn = insn.getOriginalRopInsn(); 676579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson block.replaceLastInsn(new PlainInsn(Rops.GOTO, 677579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson originalRopInsn.getPosition(), null, RegisterSpecList.EMPTY)); 678579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson block.removeSuccessor(oldSuccessor); 679579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 680579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 681579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson} 682