12502e004d93734a99bdfeab811b3c5ae06f45becbuzbee/* 22502e004d93734a99bdfeab811b3c5ae06f45becbuzbee * Copyright (C) 2012 The Android Open Source Project 32502e004d93734a99bdfeab811b3c5ae06f45becbuzbee * 42502e004d93734a99bdfeab811b3c5ae06f45becbuzbee * Licensed under the Apache License, Version 2.0 (the "License"); 52502e004d93734a99bdfeab811b3c5ae06f45becbuzbee * you may not use this file except in compliance with the License. 62502e004d93734a99bdfeab811b3c5ae06f45becbuzbee * You may obtain a copy of the License at 72502e004d93734a99bdfeab811b3c5ae06f45becbuzbee * 82502e004d93734a99bdfeab811b3c5ae06f45becbuzbee * http://www.apache.org/licenses/LICENSE-2.0 92502e004d93734a99bdfeab811b3c5ae06f45becbuzbee * 102502e004d93734a99bdfeab811b3c5ae06f45becbuzbee * Unless required by applicable law or agreed to in writing, software 112502e004d93734a99bdfeab811b3c5ae06f45becbuzbee * distributed under the License is distributed on an "AS IS" BASIS, 122502e004d93734a99bdfeab811b3c5ae06f45becbuzbee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132502e004d93734a99bdfeab811b3c5ae06f45becbuzbee * See the License for the specific language governing permissions and 142502e004d93734a99bdfeab811b3c5ae06f45becbuzbee * limitations under the License. 152502e004d93734a99bdfeab811b3c5ae06f45becbuzbee */ 162502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 17311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#include "local_value_numbering.h" 182502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 192502e004d93734a99bdfeab811b3c5ae06f45becbuzbeenamespace art { 202502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 212502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 222ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromuint16_t LocalValueNumbering::GetValueNumber(MIR* mir) { 232502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t res = NO_VALUE; 242502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t opcode = mir->dalvikInsn.opcode; 252502e004d93734a99bdfeab811b3c5ae06f45becbuzbee switch (opcode) { 262502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::NOP: 272502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::RETURN_VOID: 282502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::RETURN: 292502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::RETURN_OBJECT: 302502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::RETURN_WIDE: 312502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::MONITOR_ENTER: 322502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::MONITOR_EXIT: 332502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::GOTO: 342502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::GOTO_16: 352502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::GOTO_32: 362502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::CHECK_CAST: 372502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::THROW: 382502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::FILL_ARRAY_DATA: 392502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::FILLED_NEW_ARRAY: 402502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::FILLED_NEW_ARRAY_RANGE: 412502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::PACKED_SWITCH: 422502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SPARSE_SWITCH: 432502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::IF_EQ: 442502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::IF_NE: 452502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::IF_LT: 462502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::IF_GE: 472502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::IF_GT: 482502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::IF_LE: 492502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::IF_EQZ: 502502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::IF_NEZ: 512502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::IF_LTZ: 522502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::IF_GEZ: 532502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::IF_GTZ: 542502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::IF_LEZ: 552502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::INVOKE_STATIC_RANGE: 562502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::INVOKE_STATIC: 572502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::INVOKE_DIRECT: 582502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::INVOKE_DIRECT_RANGE: 592502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::INVOKE_VIRTUAL: 602502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::INVOKE_VIRTUAL_RANGE: 612502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::INVOKE_SUPER: 622502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::INVOKE_SUPER_RANGE: 632502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::INVOKE_INTERFACE: 642502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::INVOKE_INTERFACE_RANGE: 652502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case kMirOpFusedCmplFloat: 662502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case kMirOpFusedCmpgFloat: 672502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case kMirOpFusedCmplDouble: 682502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case kMirOpFusedCmpgDouble: 692502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case kMirOpFusedCmpLong: 702502e004d93734a99bdfeab811b3c5ae06f45becbuzbee // Nothing defined - take no action. 712502e004d93734a99bdfeab811b3c5ae06f45becbuzbee break; 722502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 732502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::MOVE_EXCEPTION: 742502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::MOVE_RESULT: 752502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::MOVE_RESULT_OBJECT: 762502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::INSTANCE_OF: 772502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::NEW_INSTANCE: 782502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::CONST_STRING: 792502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::CONST_STRING_JUMBO: 802502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::CONST_CLASS: 812502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::NEW_ARRAY: { 822502e004d93734a99bdfeab811b3c5ae06f45becbuzbee // 1 result, treat as unique each time, use result s_reg - will be unique. 832502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t res = GetOperandValue(mir->ssa_rep->defs[0]); 842502e004d93734a99bdfeab811b3c5ae06f45becbuzbee SetOperandValue(mir->ssa_rep->defs[0], res); 852502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 862502e004d93734a99bdfeab811b3c5ae06f45becbuzbee break; 872502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::MOVE_RESULT_WIDE: { 882502e004d93734a99bdfeab811b3c5ae06f45becbuzbee // 1 wide result, treat as unique each time, use result s_reg - will be unique. 892502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t res = GetOperandValueWide(mir->ssa_rep->defs[0]); 902502e004d93734a99bdfeab811b3c5ae06f45becbuzbee SetOperandValueWide(mir->ssa_rep->defs[0], res); 912502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 922502e004d93734a99bdfeab811b3c5ae06f45becbuzbee break; 932502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 942502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case kMirOpPhi: 952502e004d93734a99bdfeab811b3c5ae06f45becbuzbee /* 962502e004d93734a99bdfeab811b3c5ae06f45becbuzbee * Because we'll only see phi nodes at the beginning of an extended basic block, 972502e004d93734a99bdfeab811b3c5ae06f45becbuzbee * we can ignore them. Revisit if we shift to global value numbering. 982502e004d93734a99bdfeab811b3c5ae06f45becbuzbee */ 992502e004d93734a99bdfeab811b3c5ae06f45becbuzbee break; 1002502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 1012502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::MOVE: 1022502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::MOVE_OBJECT: 1032502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::MOVE_16: 1042502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::MOVE_OBJECT_16: 1052502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::MOVE_FROM16: 1062502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::MOVE_OBJECT_FROM16: 1072502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case kMirOpCopy: { 1082502e004d93734a99bdfeab811b3c5ae06f45becbuzbee // Just copy value number of source to value number of resulit. 1092502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t res = GetOperandValue(mir->ssa_rep->uses[0]); 1102502e004d93734a99bdfeab811b3c5ae06f45becbuzbee SetOperandValue(mir->ssa_rep->defs[0], res); 1112502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 1122502e004d93734a99bdfeab811b3c5ae06f45becbuzbee break; 1132502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 1142502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::MOVE_WIDE: 1152502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::MOVE_WIDE_16: 1162502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::MOVE_WIDE_FROM16: { 1172502e004d93734a99bdfeab811b3c5ae06f45becbuzbee // Just copy value number of source to value number of result. 1182502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t res = GetOperandValueWide(mir->ssa_rep->uses[0]); 1192502e004d93734a99bdfeab811b3c5ae06f45becbuzbee SetOperandValueWide(mir->ssa_rep->defs[0], res); 1202502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 1212502e004d93734a99bdfeab811b3c5ae06f45becbuzbee break; 1222502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 1232502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::CONST: 1242502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::CONST_4: 1252502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::CONST_16: { 1262502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t res = LookupValue(Instruction::CONST, Low16Bits(mir->dalvikInsn.vB), 1272502e004d93734a99bdfeab811b3c5ae06f45becbuzbee High16Bits(mir->dalvikInsn.vB >> 16), 0); 1282502e004d93734a99bdfeab811b3c5ae06f45becbuzbee SetOperandValue(mir->ssa_rep->defs[0], res); 1292502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 1302502e004d93734a99bdfeab811b3c5ae06f45becbuzbee break; 1312502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 1322502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::CONST_HIGH16: { 1332502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t res = LookupValue(Instruction::CONST, 0, mir->dalvikInsn.vB, 0); 1342502e004d93734a99bdfeab811b3c5ae06f45becbuzbee SetOperandValue(mir->ssa_rep->defs[0], res); 1352502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 1362502e004d93734a99bdfeab811b3c5ae06f45becbuzbee break; 1372502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 1382502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::CONST_WIDE_16: 1392502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::CONST_WIDE_32: { 1402502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t low_res = LookupValue(Instruction::CONST, Low16Bits(mir->dalvikInsn.vB), 1412502e004d93734a99bdfeab811b3c5ae06f45becbuzbee High16Bits(mir->dalvikInsn.vB >> 16), 1); 1422502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t high_res; 1432502e004d93734a99bdfeab811b3c5ae06f45becbuzbee if (mir->dalvikInsn.vB & 0x80000000) { 1442502e004d93734a99bdfeab811b3c5ae06f45becbuzbee high_res = LookupValue(Instruction::CONST, 0xffff, 0xffff, 2); 1452502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } else { 1462502e004d93734a99bdfeab811b3c5ae06f45becbuzbee high_res = LookupValue(Instruction::CONST, 0, 0, 2); 1472502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 1482502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t res = LookupValue(Instruction::CONST, low_res, high_res, 3); 1492502e004d93734a99bdfeab811b3c5ae06f45becbuzbee SetOperandValue(mir->ssa_rep->defs[0], res); 1502502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 1512502e004d93734a99bdfeab811b3c5ae06f45becbuzbee break; 1522502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 1532502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::CONST_WIDE: { 1542502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint32_t low_word = Low32Bits(mir->dalvikInsn.vB_wide); 1552502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint32_t high_word = High32Bits(mir->dalvikInsn.vB_wide); 1562502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t low_res = LookupValue(Instruction::CONST, Low16Bits(low_word), 1572502e004d93734a99bdfeab811b3c5ae06f45becbuzbee High16Bits(low_word), 1); 1582502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t high_res = LookupValue(Instruction::CONST, Low16Bits(high_word), 1592502e004d93734a99bdfeab811b3c5ae06f45becbuzbee High16Bits(high_word), 2); 1602502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t res = LookupValue(Instruction::CONST, low_res, high_res, 3); 1612502e004d93734a99bdfeab811b3c5ae06f45becbuzbee SetOperandValueWide(mir->ssa_rep->defs[0], res); 1622502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 1632502e004d93734a99bdfeab811b3c5ae06f45becbuzbee break; 1642502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 1652502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::CONST_WIDE_HIGH16: { 1662502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t low_res = LookupValue(Instruction::CONST, 0, 0, 1); 1672502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t high_res = LookupValue(Instruction::CONST, 0, Low16Bits(mir->dalvikInsn.vB), 2); 1682502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t res = LookupValue(Instruction::CONST, low_res, high_res, 3); 1692502e004d93734a99bdfeab811b3c5ae06f45becbuzbee SetOperandValueWide(mir->ssa_rep->defs[0], res); 1702502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 1712502e004d93734a99bdfeab811b3c5ae06f45becbuzbee break; 1722502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 1732502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::ARRAY_LENGTH: 1742502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::NEG_INT: 1752502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::NOT_INT: 1762502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::NEG_FLOAT: 1772502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::INT_TO_BYTE: 1782502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::INT_TO_SHORT: 1792502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::INT_TO_CHAR: 1802502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::INT_TO_FLOAT: 1812502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::FLOAT_TO_INT: { 1822502e004d93734a99bdfeab811b3c5ae06f45becbuzbee // res = op + 1 operand 1832502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t operand1 = GetOperandValue(mir->ssa_rep->uses[0]); 1842502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t res = LookupValue(opcode, operand1, NO_VALUE, NO_VALUE); 1852502e004d93734a99bdfeab811b3c5ae06f45becbuzbee SetOperandValue(mir->ssa_rep->defs[0], res); 1862502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 1872502e004d93734a99bdfeab811b3c5ae06f45becbuzbee break; 1882502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 1892502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::LONG_TO_FLOAT: 1902502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::LONG_TO_INT: 1912502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::DOUBLE_TO_FLOAT: 1922502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::DOUBLE_TO_INT: { 1932502e004d93734a99bdfeab811b3c5ae06f45becbuzbee // res = op + 1 wide operand 1942502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t operand1 = GetOperandValue(mir->ssa_rep->uses[0]); 1952502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t res = LookupValue(opcode, operand1, NO_VALUE, NO_VALUE); 1962502e004d93734a99bdfeab811b3c5ae06f45becbuzbee SetOperandValue(mir->ssa_rep->defs[0], res); 1972502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 1982502e004d93734a99bdfeab811b3c5ae06f45becbuzbee break; 1992502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 2002502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 2012502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::DOUBLE_TO_LONG: 2022502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::LONG_TO_DOUBLE: 2032502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::NEG_LONG: 2042502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::NOT_LONG: 2052502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::NEG_DOUBLE: { 2062502e004d93734a99bdfeab811b3c5ae06f45becbuzbee // wide res = op + 1 wide operand 2072502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t operand1 = GetOperandValueWide(mir->ssa_rep->uses[0]); 2082502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t res = LookupValue(opcode, operand1, NO_VALUE, NO_VALUE); 2092502e004d93734a99bdfeab811b3c5ae06f45becbuzbee SetOperandValueWide(mir->ssa_rep->defs[0], res); 2102502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 2112502e004d93734a99bdfeab811b3c5ae06f45becbuzbee break; 2122502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 2132502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::FLOAT_TO_DOUBLE: 2142502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::FLOAT_TO_LONG: 2152502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::INT_TO_DOUBLE: 2162502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::INT_TO_LONG: { 2172502e004d93734a99bdfeab811b3c5ae06f45becbuzbee // wide res = op + 1 operand 2182502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t operand1 = GetOperandValueWide(mir->ssa_rep->uses[0]); 2192502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t res = LookupValue(opcode, operand1, NO_VALUE, NO_VALUE); 2202502e004d93734a99bdfeab811b3c5ae06f45becbuzbee SetOperandValueWide(mir->ssa_rep->defs[0], res); 2212502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 2222502e004d93734a99bdfeab811b3c5ae06f45becbuzbee break; 2232502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 2242502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::CMPL_DOUBLE: 2252502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::CMPG_DOUBLE: 2262502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::CMP_LONG: { 2272502e004d93734a99bdfeab811b3c5ae06f45becbuzbee // res = op + 2 wide operands 2282502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t operand1 = GetOperandValueWide(mir->ssa_rep->uses[0]); 2292502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t operand2 = GetOperandValueWide(mir->ssa_rep->uses[2]); 2302502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t res = LookupValue(opcode, operand1, operand2, NO_VALUE); 2312502e004d93734a99bdfeab811b3c5ae06f45becbuzbee SetOperandValue(mir->ssa_rep->defs[0], res); 2322502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 2332502e004d93734a99bdfeab811b3c5ae06f45becbuzbee break; 2342502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 2352502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::CMPG_FLOAT: 2362502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::CMPL_FLOAT: 2372502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::ADD_INT: 2382502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::ADD_INT_2ADDR: 2392502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::MUL_INT: 2402502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::MUL_INT_2ADDR: 2412502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::AND_INT: 2422502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::AND_INT_2ADDR: 2432502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::OR_INT: 2442502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::OR_INT_2ADDR: 2452502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::XOR_INT: 2462502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::XOR_INT_2ADDR: 2472502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SUB_INT: 2482502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SUB_INT_2ADDR: 2492502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::DIV_INT: 2502502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::DIV_INT_2ADDR: 2512502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::REM_INT: 2522502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::REM_INT_2ADDR: 2532502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SHL_INT: 2542502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SHL_INT_2ADDR: 2552502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SHR_INT: 2562502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SHR_INT_2ADDR: 2572502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::USHR_INT: 2582502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::USHR_INT_2ADDR: { 2592502e004d93734a99bdfeab811b3c5ae06f45becbuzbee // res = op + 2 operands 2602502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t operand1 = GetOperandValue(mir->ssa_rep->uses[0]); 2612502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t operand2 = GetOperandValue(mir->ssa_rep->uses[1]); 2622502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t res = LookupValue(opcode, operand1, operand2, NO_VALUE); 2632502e004d93734a99bdfeab811b3c5ae06f45becbuzbee SetOperandValue(mir->ssa_rep->defs[0], res); 2642502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 2652502e004d93734a99bdfeab811b3c5ae06f45becbuzbee break; 2662502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 2672502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::ADD_LONG: 2682502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SUB_LONG: 2692502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::MUL_LONG: 2702502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::DIV_LONG: 2712502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::REM_LONG: 2722502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::AND_LONG: 2732502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::OR_LONG: 2742502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::XOR_LONG: 2752502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::ADD_LONG_2ADDR: 2762502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SUB_LONG_2ADDR: 2772502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::MUL_LONG_2ADDR: 2782502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::DIV_LONG_2ADDR: 2792502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::REM_LONG_2ADDR: 2802502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::AND_LONG_2ADDR: 2812502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::OR_LONG_2ADDR: 2822502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::XOR_LONG_2ADDR: 2832502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::ADD_DOUBLE: 2842502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SUB_DOUBLE: 2852502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::MUL_DOUBLE: 2862502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::DIV_DOUBLE: 2872502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::REM_DOUBLE: 2882502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::ADD_DOUBLE_2ADDR: 2892502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SUB_DOUBLE_2ADDR: 2902502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::MUL_DOUBLE_2ADDR: 2912502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::DIV_DOUBLE_2ADDR: 2922502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::REM_DOUBLE_2ADDR: { 2932502e004d93734a99bdfeab811b3c5ae06f45becbuzbee // wide res = op + 2 wide operands 2942502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t operand1 = GetOperandValueWide(mir->ssa_rep->uses[0]); 2952502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t operand2 = GetOperandValueWide(mir->ssa_rep->uses[2]); 2962502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t res = LookupValue(opcode, operand1, operand2, NO_VALUE); 2972502e004d93734a99bdfeab811b3c5ae06f45becbuzbee SetOperandValueWide(mir->ssa_rep->defs[0], res); 2982502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 2992502e004d93734a99bdfeab811b3c5ae06f45becbuzbee break; 3002502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 3012502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SHL_LONG: 3022502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SHR_LONG: 3032502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::USHR_LONG: 3042502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SHL_LONG_2ADDR: 3052502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SHR_LONG_2ADDR: 3062502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::USHR_LONG_2ADDR: { 3072502e004d93734a99bdfeab811b3c5ae06f45becbuzbee // wide res = op + 1 wide operand + 1 operand 3082502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t operand1 = GetOperandValueWide(mir->ssa_rep->uses[0]); 3092502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t operand2 = GetOperandValueWide(mir->ssa_rep->uses[2]); 3102502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t res = LookupValue(opcode, operand1, operand2, NO_VALUE); 3112502e004d93734a99bdfeab811b3c5ae06f45becbuzbee SetOperandValueWide(mir->ssa_rep->defs[0], res); 3122502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 3132502e004d93734a99bdfeab811b3c5ae06f45becbuzbee break; 3142502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 3152502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::ADD_FLOAT: 3162502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SUB_FLOAT: 3172502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::MUL_FLOAT: 3182502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::DIV_FLOAT: 3192502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::REM_FLOAT: 3202502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::ADD_FLOAT_2ADDR: 3212502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SUB_FLOAT_2ADDR: 3222502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::MUL_FLOAT_2ADDR: 3232502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::DIV_FLOAT_2ADDR: 3242502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::REM_FLOAT_2ADDR: { 3252502e004d93734a99bdfeab811b3c5ae06f45becbuzbee // res = op + 2 operands 3262502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t operand1 = GetOperandValue(mir->ssa_rep->uses[0]); 3272502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t operand2 = GetOperandValue(mir->ssa_rep->uses[1]); 3282502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t res = LookupValue(opcode, operand1, operand2, NO_VALUE); 3292502e004d93734a99bdfeab811b3c5ae06f45becbuzbee SetOperandValue(mir->ssa_rep->defs[0], res); 3302502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 3312502e004d93734a99bdfeab811b3c5ae06f45becbuzbee break; 3322502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 3332502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::RSUB_INT: 3342502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::ADD_INT_LIT16: 3352502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::MUL_INT_LIT16: 3362502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::DIV_INT_LIT16: 3372502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::REM_INT_LIT16: 3382502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::AND_INT_LIT16: 3392502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::OR_INT_LIT16: 3402502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::XOR_INT_LIT16: 3412502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::ADD_INT_LIT8: 3422502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::RSUB_INT_LIT8: 3432502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::MUL_INT_LIT8: 3442502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::DIV_INT_LIT8: 3452502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::REM_INT_LIT8: 3462502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::AND_INT_LIT8: 3472502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::OR_INT_LIT8: 3482502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::XOR_INT_LIT8: 3492502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SHL_INT_LIT8: 3502502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SHR_INT_LIT8: 3512502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::USHR_INT_LIT8: { 3522502e004d93734a99bdfeab811b3c5ae06f45becbuzbee // Same as res = op + 2 operands, except use vB as operand 2 3532502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t operand1 = GetOperandValue(mir->ssa_rep->uses[0]); 3542502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t operand2 = LookupValue(Instruction::CONST, mir->dalvikInsn.vB, 0, 0); 3552502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t res = LookupValue(opcode, operand1, operand2, NO_VALUE); 3562502e004d93734a99bdfeab811b3c5ae06f45becbuzbee SetOperandValue(mir->ssa_rep->defs[0], res); 3572502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 3582502e004d93734a99bdfeab811b3c5ae06f45becbuzbee break; 3592502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 3602502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::AGET_WIDE: 3612502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::AGET: 3622502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::AGET_OBJECT: 3632502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::AGET_BOOLEAN: 3642502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::AGET_BYTE: 3652502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::AGET_CHAR: 3662502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::AGET_SHORT: { 3672502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t array = GetOperandValue(mir->ssa_rep->uses[0]); 3682502e004d93734a99bdfeab811b3c5ae06f45becbuzbee if (null_checked_.find(array) != null_checked_.end()) { 3692502e004d93734a99bdfeab811b3c5ae06f45becbuzbee if (cu_->verbose) { 3702502e004d93734a99bdfeab811b3c5ae06f45becbuzbee LOG(INFO) << "Removing null check for 0x" << std::hex << mir->offset; 3712502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 3722502e004d93734a99bdfeab811b3c5ae06f45becbuzbee mir->optimization_flags |= MIR_IGNORE_NULL_CHECK; 3732502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } else { 3742502e004d93734a99bdfeab811b3c5ae06f45becbuzbee null_checked_.insert(array); 3752502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 3762502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t index = GetOperandValue(mir->ssa_rep->uses[1]); 3772502e004d93734a99bdfeab811b3c5ae06f45becbuzbee if (ValueExists(ARRAY_REF, array, index, NO_VALUE)) { 3782502e004d93734a99bdfeab811b3c5ae06f45becbuzbee if (cu_->verbose) { 3792502e004d93734a99bdfeab811b3c5ae06f45becbuzbee LOG(INFO) << "Removing range check for 0x" << std::hex << mir->offset; 3802502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 3812502e004d93734a99bdfeab811b3c5ae06f45becbuzbee mir->optimization_flags |= MIR_IGNORE_RANGE_CHECK; 3822502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 3832502e004d93734a99bdfeab811b3c5ae06f45becbuzbee mir->meta.throw_insn->optimization_flags |= mir->optimization_flags; 3842502e004d93734a99bdfeab811b3c5ae06f45becbuzbee // Use side effect to note range check completed. 3852502e004d93734a99bdfeab811b3c5ae06f45becbuzbee (void)LookupValue(ARRAY_REF, array, index, NO_VALUE); 3862502e004d93734a99bdfeab811b3c5ae06f45becbuzbee // Establish value number for loaded register. Note use of memory version. 3872502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t memory_version = GetMemoryVersion(array, NO_VALUE); 3882502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t res = LookupValue(ARRAY_REF, array, index, memory_version); 3892502e004d93734a99bdfeab811b3c5ae06f45becbuzbee if (opcode == Instruction::AGET_WIDE) { 3902502e004d93734a99bdfeab811b3c5ae06f45becbuzbee SetOperandValueWide(mir->ssa_rep->defs[0], res); 3912502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } else { 3922502e004d93734a99bdfeab811b3c5ae06f45becbuzbee SetOperandValue(mir->ssa_rep->defs[0], res); 3932502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 3942502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 3952502e004d93734a99bdfeab811b3c5ae06f45becbuzbee break; 3962502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 3972502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::APUT_WIDE: 3982502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::APUT: 3992502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::APUT_OBJECT: 4002502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::APUT_SHORT: 4012502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::APUT_CHAR: 4022502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::APUT_BYTE: 4032502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::APUT_BOOLEAN: { 4042502e004d93734a99bdfeab811b3c5ae06f45becbuzbee int array_idx = (opcode == Instruction::APUT_WIDE) ? 2 : 1; 4052502e004d93734a99bdfeab811b3c5ae06f45becbuzbee int index_idx = array_idx + 1; 4062502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t array = GetOperandValue(mir->ssa_rep->uses[array_idx]); 4072502e004d93734a99bdfeab811b3c5ae06f45becbuzbee if (null_checked_.find(array) != null_checked_.end()) { 4082502e004d93734a99bdfeab811b3c5ae06f45becbuzbee if (cu_->verbose) { 4092502e004d93734a99bdfeab811b3c5ae06f45becbuzbee LOG(INFO) << "Removing range check for 0x" << std::hex << mir->offset; 4102502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 4112502e004d93734a99bdfeab811b3c5ae06f45becbuzbee mir->optimization_flags |= MIR_IGNORE_NULL_CHECK; 4122502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } else { 4132502e004d93734a99bdfeab811b3c5ae06f45becbuzbee null_checked_.insert(array); 4142502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 4152502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t index = GetOperandValue(mir->ssa_rep->uses[index_idx]); 4162502e004d93734a99bdfeab811b3c5ae06f45becbuzbee if (ValueExists(ARRAY_REF, array, index, NO_VALUE)) { 4172502e004d93734a99bdfeab811b3c5ae06f45becbuzbee if (cu_->verbose) { 4182502e004d93734a99bdfeab811b3c5ae06f45becbuzbee LOG(INFO) << "Removing range check for 0x" << std::hex << mir->offset; 4192502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 4202502e004d93734a99bdfeab811b3c5ae06f45becbuzbee mir->optimization_flags |= MIR_IGNORE_RANGE_CHECK; 4212502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 4222502e004d93734a99bdfeab811b3c5ae06f45becbuzbee mir->meta.throw_insn->optimization_flags |= mir->optimization_flags; 4232502e004d93734a99bdfeab811b3c5ae06f45becbuzbee // Use side effect to note range check completed. 4242502e004d93734a99bdfeab811b3c5ae06f45becbuzbee (void)LookupValue(ARRAY_REF, array, index, NO_VALUE); 4252502e004d93734a99bdfeab811b3c5ae06f45becbuzbee // Rev the memory version 4262502e004d93734a99bdfeab811b3c5ae06f45becbuzbee AdvanceMemoryVersion(array, NO_VALUE); 4272502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 4282502e004d93734a99bdfeab811b3c5ae06f45becbuzbee break; 4292502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 4302502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::IGET_OBJECT: 4312502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::IGET_WIDE: 4322502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::IGET: 4332502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::IGET_CHAR: 4342502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::IGET_SHORT: 4352502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::IGET_BOOLEAN: 4362502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::IGET_BYTE: { 4372502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t base = GetOperandValue(mir->ssa_rep->uses[0]); 4382502e004d93734a99bdfeab811b3c5ae06f45becbuzbee if (null_checked_.find(base) != null_checked_.end()) { 4392502e004d93734a99bdfeab811b3c5ae06f45becbuzbee if (cu_->verbose) { 4402502e004d93734a99bdfeab811b3c5ae06f45becbuzbee LOG(INFO) << "Removing null check for 0x" << std::hex << mir->offset; 4412502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 4422502e004d93734a99bdfeab811b3c5ae06f45becbuzbee mir->optimization_flags |= MIR_IGNORE_NULL_CHECK; 4432502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } else { 4442502e004d93734a99bdfeab811b3c5ae06f45becbuzbee null_checked_.insert(base); 4452502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 4462502e004d93734a99bdfeab811b3c5ae06f45becbuzbee mir->meta.throw_insn->optimization_flags |= mir->optimization_flags; 4472502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t field_ref = mir->dalvikInsn.vC; 4482502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t memory_version = GetMemoryVersion(base, field_ref); 4492502e004d93734a99bdfeab811b3c5ae06f45becbuzbee if (opcode == Instruction::IGET_WIDE) { 4502502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t res = LookupValue(Instruction::IGET_WIDE, base, field_ref, memory_version); 4512502e004d93734a99bdfeab811b3c5ae06f45becbuzbee SetOperandValueWide(mir->ssa_rep->defs[0], res); 4522502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } else { 4532502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t res = LookupValue(Instruction::IGET, base, field_ref, memory_version); 4542502e004d93734a99bdfeab811b3c5ae06f45becbuzbee SetOperandValue(mir->ssa_rep->defs[0], res); 4552502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 4562502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 4572502e004d93734a99bdfeab811b3c5ae06f45becbuzbee break; 4582502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 4592502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::IPUT_WIDE: 4602502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::IPUT_OBJECT: 4612502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::IPUT: 4622502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::IPUT_BOOLEAN: 4632502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::IPUT_BYTE: 4642502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::IPUT_CHAR: 4652502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::IPUT_SHORT: { 4662502e004d93734a99bdfeab811b3c5ae06f45becbuzbee int base_reg = (opcode == Instruction::IPUT_WIDE) ? 2 : 1; 4672502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t base = GetOperandValue(mir->ssa_rep->uses[base_reg]); 4682502e004d93734a99bdfeab811b3c5ae06f45becbuzbee if (null_checked_.find(base) != null_checked_.end()) { 4692502e004d93734a99bdfeab811b3c5ae06f45becbuzbee if (cu_->verbose) { 4702502e004d93734a99bdfeab811b3c5ae06f45becbuzbee LOG(INFO) << "Removing null check for 0x" << std::hex << mir->offset; 4712502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 4722502e004d93734a99bdfeab811b3c5ae06f45becbuzbee mir->optimization_flags |= MIR_IGNORE_NULL_CHECK; 4732502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } else { 4742502e004d93734a99bdfeab811b3c5ae06f45becbuzbee null_checked_.insert(base); 4752502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 4762502e004d93734a99bdfeab811b3c5ae06f45becbuzbee mir->meta.throw_insn->optimization_flags |= mir->optimization_flags; 4772502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t field_ref = mir->dalvikInsn.vC; 4782502e004d93734a99bdfeab811b3c5ae06f45becbuzbee AdvanceMemoryVersion(base, field_ref); 4792502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 4802502e004d93734a99bdfeab811b3c5ae06f45becbuzbee break; 4812502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 4822502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SGET_OBJECT: 4832502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SGET: 4842502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SGET_BOOLEAN: 4852502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SGET_BYTE: 4862502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SGET_CHAR: 4872502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SGET_SHORT: 4882502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SGET_WIDE: { 4892502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t field_ref = mir->dalvikInsn.vB; 4902502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t memory_version = GetMemoryVersion(NO_VALUE, field_ref); 4912502e004d93734a99bdfeab811b3c5ae06f45becbuzbee if (opcode == Instruction::SGET_WIDE) { 4922502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t res = LookupValue(Instruction::SGET_WIDE, NO_VALUE, field_ref, memory_version); 4932502e004d93734a99bdfeab811b3c5ae06f45becbuzbee SetOperandValueWide(mir->ssa_rep->defs[0], res); 4942502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } else { 4952502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t res = LookupValue(Instruction::SGET, NO_VALUE, field_ref, memory_version); 4962502e004d93734a99bdfeab811b3c5ae06f45becbuzbee SetOperandValue(mir->ssa_rep->defs[0], res); 4972502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 4982502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 4992502e004d93734a99bdfeab811b3c5ae06f45becbuzbee break; 5002502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 5012502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SPUT_OBJECT: 5022502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SPUT: 5032502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SPUT_BOOLEAN: 5042502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SPUT_BYTE: 5052502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SPUT_CHAR: 5062502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SPUT_SHORT: 5072502e004d93734a99bdfeab811b3c5ae06f45becbuzbee case Instruction::SPUT_WIDE: { 5082502e004d93734a99bdfeab811b3c5ae06f45becbuzbee uint16_t field_ref = mir->dalvikInsn.vB; 5092502e004d93734a99bdfeab811b3c5ae06f45becbuzbee AdvanceMemoryVersion(NO_VALUE, field_ref); 5102502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 5112502e004d93734a99bdfeab811b3c5ae06f45becbuzbee break; 5122502e004d93734a99bdfeab811b3c5ae06f45becbuzbee } 5132502e004d93734a99bdfeab811b3c5ae06f45becbuzbee return res; 5142502e004d93734a99bdfeab811b3c5ae06f45becbuzbee} 5152502e004d93734a99bdfeab811b3c5ae06f45becbuzbee 5162502e004d93734a99bdfeab811b3c5ae06f45becbuzbee} // namespace art 517