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