mir_graph.cc revision 1c6ea4483982803b3bc3635b7dd71744c1fe1cef
1311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/* 2311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Copyright (C) 2013 The Android Open Source Project 3311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * 4311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Licensed under the Apache License, Version 2.0 (the "License"); 5311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * you may not use this file except in compliance with the License. 6311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * You may obtain a copy of the License at 7311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * 8311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * http://www.apache.org/licenses/LICENSE-2.0 9311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * 10311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Unless required by applicable law or agreed to in writing, software 11311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * distributed under the License is distributed on an "AS IS" BASIS, 12311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * See the License for the specific language governing permissions and 14311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * limitations under the License. 15311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 16311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 17f3e2cc4a38389aa75eb8ee3973a535254bf1c8d2Nicolas Geoffray#include "mir_graph.h" 18f3e2cc4a38389aa75eb8ee3973a535254bf1c8d2Nicolas Geoffray 19f3e2cc4a38389aa75eb8ee3973a535254bf1c8d2Nicolas Geoffray#include <inttypes.h> 2044e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler#include <queue> 21f3e2cc4a38389aa75eb8ee3973a535254bf1c8d2Nicolas Geoffray 22e77493c7217efdd1a0ecef521a6845a13da0305bIan Rogers#include "base/bit_vector-inl.h" 236282dc12440a2072dc06a616160027ff21bd895eIan Rogers#include "base/stl_util.h" 24311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#include "compiler_internals.h" 25311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#include "dex_file-inl.h" 2629a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers#include "dex_instruction-inl.h" 2795a059793c4c194f026afc74c713cc295d75d91aVladimir Marko#include "dex/global_value_numbering.h" 285816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko#include "dex/quick/dex_file_to_method_inliner_map.h" 295816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko#include "dex/quick/dex_file_method_inliner.h" 30f3e2cc4a38389aa75eb8ee3973a535254bf1c8d2Nicolas Geoffray#include "leb128.h" 312469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler#include "pass_driver_me_post_opt.h" 3253c913bb71b218714823c8c87a1f92830c336f61Andreas Gampe#include "stack.h" 33622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko#include "utils/scoped_arena_containers.h" 345816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko 35311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeenamespace art { 36311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 37311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define MAX_PATTERN_LEN 5 38311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 391fd3346740dfb7f47be9922312b68a4227fada96buzbeeconst char* MIRGraph::extended_mir_op_names_[kMirOpLast - kMirOpFirst] = { 401fd3346740dfb7f47be9922312b68a4227fada96buzbee "Phi", 411fd3346740dfb7f47be9922312b68a4227fada96buzbee "Copy", 421fd3346740dfb7f47be9922312b68a4227fada96buzbee "FusedCmplFloat", 431fd3346740dfb7f47be9922312b68a4227fada96buzbee "FusedCmpgFloat", 441fd3346740dfb7f47be9922312b68a4227fada96buzbee "FusedCmplDouble", 451fd3346740dfb7f47be9922312b68a4227fada96buzbee "FusedCmpgDouble", 461fd3346740dfb7f47be9922312b68a4227fada96buzbee "FusedCmpLong", 471fd3346740dfb7f47be9922312b68a4227fada96buzbee "Nop", 481fd3346740dfb7f47be9922312b68a4227fada96buzbee "OpNullCheck", 491fd3346740dfb7f47be9922312b68a4227fada96buzbee "OpRangeCheck", 501fd3346740dfb7f47be9922312b68a4227fada96buzbee "OpDivZeroCheck", 511fd3346740dfb7f47be9922312b68a4227fada96buzbee "Check1", 521fd3346740dfb7f47be9922312b68a4227fada96buzbee "Check2", 531fd3346740dfb7f47be9922312b68a4227fada96buzbee "Select", 54d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell "ConstVector", 55d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell "MoveVector", 56d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell "PackedMultiply", 57d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell "PackedAddition", 58d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell "PackedSubtract", 59d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell "PackedShiftLeft", 60d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell "PackedSignedShiftRight", 61d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell "PackedUnsignedShiftRight", 62d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell "PackedAnd", 63d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell "PackedOr", 64d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell "PackedXor", 65d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell "PackedAddReduce", 66d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell "PackedReduce", 67d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell "PackedSet", 6860bfe7b3e8f00f0a8ef3f5d8716adfdf86b71f43Udayan Banerji "ReserveVectorRegisters", 6960bfe7b3e8f00f0a8ef3f5d8716adfdf86b71f43Udayan Banerji "ReturnVectorRegisters", 70b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler "MemBarrier", 71b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A "PackedArrayGet", 72b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A "PackedArrayPut", 73a262f7707330dccfb50af6345813083182b61043Ningsheng Jian "MaddInt", 74a262f7707330dccfb50af6345813083182b61043Ningsheng Jian "MsubInt", 75a262f7707330dccfb50af6345813083182b61043Ningsheng Jian "MaddLong", 76a262f7707330dccfb50af6345813083182b61043Ningsheng Jian "MsubLong", 771fd3346740dfb7f47be9922312b68a4227fada96buzbee}; 781fd3346740dfb7f47be9922312b68a4227fada96buzbee 79862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbeeMIRGraph::MIRGraph(CompilationUnit* cu, ArenaAllocator* arena) 801fd3346740dfb7f47be9922312b68a4227fada96buzbee : reg_location_(NULL), 818081d2b8d7a743729557051d0294e040e61c747aVladimir Marko block_id_map_(std::less<unsigned int>(), arena->Adapter()), 821fd3346740dfb7f47be9922312b68a4227fada96buzbee cu_(cu), 83e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko ssa_base_vregs_(arena->Adapter(kArenaAllocSSAToDalvikMap)), 84e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko ssa_subscripts_(arena->Adapter(kArenaAllocSSAToDalvikMap)), 851c6ea4483982803b3bc3635b7dd71744c1fe1cefVladimir Marko vreg_to_ssa_map_(NULL), 861c6ea4483982803b3bc3635b7dd71744c1fe1cefVladimir Marko ssa_last_defs_(NULL), 87311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee is_constant_v_(NULL), 88311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee constant_values_(NULL), 89e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko use_counts_(arena->Adapter()), 90e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko raw_use_counts_(arena->Adapter()), 91311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee num_reachable_blocks_(0), 924896d7b6fb75add25f2d6ba84346ac83d8ba9d51Jean Christophe Beyler max_num_reachable_blocks_(0), 93312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko dfs_orders_up_to_date_(false), 94ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko domination_up_to_date_(false), 95ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko mir_ssa_rep_up_to_date_(false), 96ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko topological_order_up_to_date_(false), 97e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko dfs_order_(arena->Adapter(kArenaAllocDfsPreOrder)), 98e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko dfs_post_order_(arena->Adapter(kArenaAllocDfsPostOrder)), 99e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko dom_post_order_traversal_(arena->Adapter(kArenaAllocDomPostOrder)), 100e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_(arena->Adapter(kArenaAllocTopologicalSortOrder)), 101e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_loop_ends_(arena->Adapter(kArenaAllocTopologicalSortOrder)), 102e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_indexes_(arena->Adapter(kArenaAllocTopologicalSortOrder)), 103e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_loop_head_stack_(arena->Adapter(kArenaAllocTopologicalSortOrder)), 104415ac88a6471792a28cf2b457fe4ba9dc099396eVladimir Marko max_nested_loops_(0u), 105311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee i_dom_list_(NULL), 106bfea9c29e809e04bde4a46591fea64c5a7b922fbVladimir Marko temp_scoped_alloc_(), 107e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko block_list_(arena->Adapter(kArenaAllocBBList)), 108311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee try_block_addr_(NULL), 109311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee entry_block_(NULL), 110311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee exit_block_(NULL), 111311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee current_code_item_(NULL), 112e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko dex_pc_to_block_map_(arena->Adapter()), 1138081d2b8d7a743729557051d0294e040e61c747aVladimir Marko m_units_(arena->Adapter()), 1148081d2b8d7a743729557051d0294e040e61c747aVladimir Marko method_stack_(arena->Adapter()), 115311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee current_method_(kInvalidEntry), 116311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee current_offset_(kInvalidEntry), 117311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee def_count_(0), 118311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee opcode_count_(NULL), 1191fd3346740dfb7f47be9922312b68a4227fada96buzbee num_ssa_regs_(0), 1208081d2b8d7a743729557051d0294e040e61c747aVladimir Marko extended_basic_blocks_(arena->Adapter()), 1211fd3346740dfb7f47be9922312b68a4227fada96buzbee method_sreg_(0), 122862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee attributes_(METHOD_IS_LEAF), // Start with leaf assumption, change on encountering invoke. 123862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee checkstats_(NULL), 124b48819db07f9a0992a72173380c24249d7fc648abuzbee arena_(arena), 125b48819db07f9a0992a72173380c24249d7fc648abuzbee backward_branches_(0), 126da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru forward_branches_(0), 127da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru num_non_special_compiler_temps_(0), 1288d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru max_available_special_compiler_temps_(1), // We only need the method ptr as a special temp for now. 1298d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru requested_backend_temp_(false), 1308d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru compiler_temps_committed_(false), 131be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko punt_to_interpreter_(false), 1323d73ba2ce682edfaf41f29521bd6039c6499a1c5Vladimir Marko merged_df_flags_(0u), 133e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko ifield_lowering_infos_(arena->Adapter(kArenaAllocLoweringInfo)), 134e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko sfield_lowering_infos_(arena->Adapter(kArenaAllocLoweringInfo)), 135e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko method_lowering_infos_(arena->Adapter(kArenaAllocLoweringInfo)), 1368b858e16563ebf8e522df026a6ab409f1bd9b3deVladimir Marko suspend_checks_in_loops_(nullptr) { 137f585e549682a98eec12f92033e9634dc162b7df8Vladimir Marko memset(&temp_, 0, sizeof(temp_)); 138e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko use_counts_.reserve(256); 139e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko raw_use_counts_.reserve(256); 140e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko block_list_.reserve(100); 141862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee try_block_addr_ = new (arena_) ArenaBitVector(arena_, 0, true /* expandable */); 1428d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru 1438d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru 1448d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru if (cu_->instruction_set == kX86 || cu_->instruction_set == kX86_64) { 1458d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru // X86 requires a temp to keep track of the method address. 1468d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru // TODO For x86_64, addressing can be done with RIP. When that is implemented, 1478d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru // this needs to be updated to reserve 0 temps for BE. 1488d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru max_available_non_special_compiler_temps_ = cu_->target64 ? 2 : 1; 1498d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru reserved_temps_for_backend_ = max_available_non_special_compiler_temps_; 1508d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru } else { 1518d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru // Other architectures do not have a known lower bound for non-special temps. 1528d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru // We allow the update of the max to happen at BE initialization stage and simply set 0 for now. 1538d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru max_available_non_special_compiler_temps_ = 0; 1548d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru reserved_temps_for_backend_ = 0; 1558d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru } 156311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 157311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 1586282dc12440a2072dc06a616160027ff21bd895eIan RogersMIRGraph::~MIRGraph() { 159e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko STLDeleteElements(&block_list_); 1606282dc12440a2072dc06a616160027ff21bd895eIan Rogers STLDeleteElements(&m_units_); 1616282dc12440a2072dc06a616160027ff21bd895eIan Rogers} 1626282dc12440a2072dc06a616160027ff21bd895eIan Rogers 163311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/* 164311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Parse an instruction, return the length of the instruction 165311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 16629a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogersint MIRGraph::ParseInsn(const uint16_t* code_ptr, MIR::DecodedInstruction* decoded_instruction) { 16729a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers const Instruction* inst = Instruction::At(code_ptr); 16829a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers decoded_instruction->opcode = inst->Opcode(); 16929a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers decoded_instruction->vA = inst->HasVRegA() ? inst->VRegA() : 0; 17029a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers decoded_instruction->vB = inst->HasVRegB() ? inst->VRegB() : 0; 17129a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers decoded_instruction->vB_wide = inst->HasWideVRegB() ? inst->WideVRegB() : 0; 17229a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers decoded_instruction->vC = inst->HasVRegC() ? inst->VRegC() : 0; 17329a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers if (inst->HasVarArgs()) { 17429a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers inst->GetVarArgs(decoded_instruction->arg); 17529a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers } 17629a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers return inst->SizeInCodeUnits(); 177311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 178311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 179311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 180311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/* Split an existing block from the specified code offset into two */ 1810d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeBasicBlock* MIRGraph::SplitBlock(DexOffset code_offset, 1822ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom BasicBlock* orig_block, BasicBlock** immed_pred_block_p) { 1830d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DCHECK_GT(code_offset, orig_block->start_offset); 184311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee MIR* insn = orig_block->first_mir_insn; 18533c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski MIR* prev = NULL; // Will be set to instruction before split. 186311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee while (insn) { 187311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (insn->offset == code_offset) break; 1880d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee prev = insn; 189311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee insn = insn->next; 190311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 191311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (insn == NULL) { 192311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee LOG(FATAL) << "Break split failed"; 193311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 19433c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski // Now insn is at the instruction where we want to split, namely 19533c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski // insn will be the first instruction of the "bottom" block. 19633c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski // Similarly, prev will be the last instruction of the "top" block 19733c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski 198e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* bottom_block = CreateNewBB(kDalvikByteCode); 199311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 200311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bottom_block->start_offset = code_offset; 201311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bottom_block->first_mir_insn = insn; 202311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bottom_block->last_mir_insn = orig_block->last_mir_insn; 203311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 20490223cc2e0bfb5a2b55e9ffed896ef327b9f3d2eJunmo Park /* If this block was terminated by a return, conditional branch or throw, 20590223cc2e0bfb5a2b55e9ffed896ef327b9f3d2eJunmo Park * the flag needs to go with the bottom block 20690223cc2e0bfb5a2b55e9ffed896ef327b9f3d2eJunmo Park */ 207311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bottom_block->terminated_by_return = orig_block->terminated_by_return; 208311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee orig_block->terminated_by_return = false; 209311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 21090223cc2e0bfb5a2b55e9ffed896ef327b9f3d2eJunmo Park bottom_block->conditional_branch = orig_block->conditional_branch; 21190223cc2e0bfb5a2b55e9ffed896ef327b9f3d2eJunmo Park orig_block->conditional_branch = false; 21290223cc2e0bfb5a2b55e9ffed896ef327b9f3d2eJunmo Park 21390223cc2e0bfb5a2b55e9ffed896ef327b9f3d2eJunmo Park bottom_block->explicit_throw = orig_block->explicit_throw; 21490223cc2e0bfb5a2b55e9ffed896ef327b9f3d2eJunmo Park orig_block->explicit_throw = false; 21590223cc2e0bfb5a2b55e9ffed896ef327b9f3d2eJunmo Park 216311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* Handle the taken path */ 217311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bottom_block->taken = orig_block->taken; 2180d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (bottom_block->taken != NullBasicBlockId) { 2190d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee orig_block->taken = NullBasicBlockId; 2200d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee BasicBlock* bb_taken = GetBasicBlock(bottom_block->taken); 221e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bb_taken->ErasePredecessor(orig_block->id); 222e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bb_taken->predecessors.push_back(bottom_block->id); 223311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 224311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 225311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* Handle the fallthrough path */ 226311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bottom_block->fall_through = orig_block->fall_through; 2270d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee orig_block->fall_through = bottom_block->id; 228e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bottom_block->predecessors.push_back(orig_block->id); 2290d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (bottom_block->fall_through != NullBasicBlockId) { 2300d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee BasicBlock* bb_fall_through = GetBasicBlock(bottom_block->fall_through); 231e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bb_fall_through->ErasePredecessor(orig_block->id); 232e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bb_fall_through->predecessors.push_back(bottom_block->id); 233311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 234311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 235311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* Handle the successor list */ 2360d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (orig_block->successor_block_list_type != kNotUsed) { 2370d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee bottom_block->successor_block_list_type = orig_block->successor_block_list_type; 238e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bottom_block->successor_blocks.swap(orig_block->successor_blocks); 2390d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee orig_block->successor_block_list_type = kNotUsed; 240e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko DCHECK(orig_block->successor_blocks.empty()); // Empty after the swap() above. 241e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (SuccessorBlockInfo* successor_block_info : bottom_block->successor_blocks) { 2428512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler BasicBlock* bb = GetBasicBlock(successor_block_info->block); 243989367a47b015dd85f850cf756b436fb044b5aeaNiranjan Kumar if (bb != nullptr) { 244e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bb->ErasePredecessor(orig_block->id); 245e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bb->predecessors.push_back(bottom_block->id); 246989367a47b015dd85f850cf756b436fb044b5aeaNiranjan Kumar } 247311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 248311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 249311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 2500d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee orig_block->last_mir_insn = prev; 2513aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler prev->next = nullptr; 252311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 253311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* 254311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Update the immediate predecessor block pointer so that outgoing edges 255311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * can be applied to the proper block. 256311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 257311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (immed_pred_block_p) { 258311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee DCHECK_EQ(*immed_pred_block_p, orig_block); 259311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee *immed_pred_block_p = bottom_block; 260311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 261b48819db07f9a0992a72173380c24249d7fc648abuzbee 262b48819db07f9a0992a72173380c24249d7fc648abuzbee // Associate dex instructions in the bottom block with the new container. 2634376c87eb45b287fad77a16738e76ba28956ab7dVladimir Marko DCHECK(insn != nullptr); 2644376c87eb45b287fad77a16738e76ba28956ab7dVladimir Marko DCHECK(insn != orig_block->first_mir_insn); 2654376c87eb45b287fad77a16738e76ba28956ab7dVladimir Marko DCHECK(insn == bottom_block->first_mir_insn); 2664376c87eb45b287fad77a16738e76ba28956ab7dVladimir Marko DCHECK_EQ(insn->offset, bottom_block->start_offset); 267e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko DCHECK_EQ(dex_pc_to_block_map_[insn->offset], orig_block->id); 26833c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski // Scan the "bottom" instructions, remapping them to the 26933c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski // newly created "bottom" block. 2704376c87eb45b287fad77a16738e76ba28956ab7dVladimir Marko MIR* p = insn; 27133c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski p->bb = bottom_block->id; 272e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko dex_pc_to_block_map_[p->offset] = bottom_block->id; 2734376c87eb45b287fad77a16738e76ba28956ab7dVladimir Marko while (p != bottom_block->last_mir_insn) { 2744376c87eb45b287fad77a16738e76ba28956ab7dVladimir Marko p = p->next; 2754376c87eb45b287fad77a16738e76ba28956ab7dVladimir Marko DCHECK(p != nullptr); 2763aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler p->bb = bottom_block->id; 277b48819db07f9a0992a72173380c24249d7fc648abuzbee int opcode = p->dalvikInsn.opcode; 278b48819db07f9a0992a72173380c24249d7fc648abuzbee /* 279b48819db07f9a0992a72173380c24249d7fc648abuzbee * Some messiness here to ensure that we only enter real opcodes and only the 280b48819db07f9a0992a72173380c24249d7fc648abuzbee * first half of a potentially throwing instruction that has been split into 2814376c87eb45b287fad77a16738e76ba28956ab7dVladimir Marko * CHECK and work portions. Since the 2nd half of a split operation is always 2824376c87eb45b287fad77a16738e76ba28956ab7dVladimir Marko * the first in a BasicBlock, we can't hit it here. 283b48819db07f9a0992a72173380c24249d7fc648abuzbee */ 2842ab40eb3c23559205ac7b9b039bd749458e8a761Jean Christophe Beyler if ((opcode == kMirOpCheck) || !MIR::DecodedInstruction::IsPseudoMirOp(opcode)) { 28533c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski BasicBlockId mapped_id = dex_pc_to_block_map_[p->offset]; 28633c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski // At first glance the instructions should all be mapped to orig_block. 28733c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski // However, multiple instructions may correspond to the same dex, hence an earlier 28833c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski // instruction may have already moved the mapping for dex to bottom_block. 28933c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski DCHECK((mapped_id == orig_block->id) || (mapped_id == bottom_block->id)); 290e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko dex_pc_to_block_map_[p->offset] = bottom_block->id; 291b48819db07f9a0992a72173380c24249d7fc648abuzbee } 292b48819db07f9a0992a72173380c24249d7fc648abuzbee } 293b48819db07f9a0992a72173380c24249d7fc648abuzbee 294311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee return bottom_block; 295311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 296311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 297311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/* 298311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Given a code offset, find out the block that starts with it. If the offset 299311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * is in the middle of an existing block, split it into two. If immed_pred_block_p 300311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * is not non-null and is the block being split, update *immed_pred_block_p to 301311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * point to the bottom block so that outgoing edges can be set up properly 302311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * (by the caller) 303311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Utilizes a map for fast lookup of the typical cases. 304311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 3056a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan RogersBasicBlock* MIRGraph::FindBlock(DexOffset code_offset, bool create, 3062ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom BasicBlock** immed_pred_block_p) { 30709ae022f55ab27edf4802baf7a05e76d7dc823a9Razvan A Lupusoru if (code_offset >= current_code_item_->insns_size_in_code_units_) { 3086a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers return nullptr; 309311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 310b48819db07f9a0992a72173380c24249d7fc648abuzbee 311e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko int block_id = dex_pc_to_block_map_[code_offset]; 312e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* bb = GetBasicBlock(block_id); 313b48819db07f9a0992a72173380c24249d7fc648abuzbee 3146a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers if ((bb != nullptr) && (bb->start_offset == code_offset)) { 315b48819db07f9a0992a72173380c24249d7fc648abuzbee // Does this containing block start with the desired instruction? 316bd663de599b16229085759366c56e2ed5a1dc7ecbuzbee return bb; 317bd663de599b16229085759366c56e2ed5a1dc7ecbuzbee } 318311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 319b48819db07f9a0992a72173380c24249d7fc648abuzbee // No direct hit. 320b48819db07f9a0992a72173380c24249d7fc648abuzbee if (!create) { 3216a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers return nullptr; 322b48819db07f9a0992a72173380c24249d7fc648abuzbee } 323b48819db07f9a0992a72173380c24249d7fc648abuzbee 3246a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers if (bb != nullptr) { 325b48819db07f9a0992a72173380c24249d7fc648abuzbee // The target exists somewhere in an existing block. 3266a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers return SplitBlock(code_offset, bb, bb == *immed_pred_block_p ? immed_pred_block_p : nullptr); 327311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 328311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 329b48819db07f9a0992a72173380c24249d7fc648abuzbee // Create a new block. 330e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bb = CreateNewBB(kDalvikByteCode); 331311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bb->start_offset = code_offset; 332e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko dex_pc_to_block_map_[bb->start_offset] = bb->id; 333311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee return bb; 334311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 335311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 336b48819db07f9a0992a72173380c24249d7fc648abuzbee 337311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/* Identify code range in try blocks and set up the empty catch blocks */ 3382ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MIRGraph::ProcessTryCatchBlocks() { 339311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int tries_size = current_code_item_->tries_size_; 3400d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DexOffset offset; 341311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 342311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (tries_size == 0) { 343311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee return; 344311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 345311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 346311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (int i = 0; i < tries_size; i++) { 347311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee const DexFile::TryItem* pTry = 348311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee DexFile::GetTryItems(*current_code_item_, i); 3490d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DexOffset start_offset = pTry->start_addr_; 3500d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DexOffset end_offset = start_offset + pTry->insn_count_; 351311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (offset = start_offset; offset < end_offset; offset++) { 352862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee try_block_addr_->SetBit(offset); 353311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 354311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 355311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 3568512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Iterate over each of the handlers to enqueue the empty Catch blocks. 35713735955f39b3b304c37d2b2840663c131262c18Ian Rogers const uint8_t* handlers_ptr = DexFile::GetCatchHandlerData(*current_code_item_, 0); 358311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr); 359311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (uint32_t idx = 0; idx < handlers_size; idx++) { 360311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee CatchHandlerIterator iterator(handlers_ptr); 361311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (; iterator.HasNext(); iterator.Next()) { 362311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee uint32_t address = iterator.GetHandlerAddress(); 3636a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers FindBlock(address, true /*create*/, /* immed_pred_block_p */ nullptr); 364311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 365311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee handlers_ptr = iterator.EndDataPointer(); 366311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 367311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 368311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 369e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Markobool MIRGraph::IsBadMonitorExitCatch(NarrowDexOffset monitor_exit_offset, 370e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko NarrowDexOffset catch_offset) { 371e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko // Catches for monitor-exit during stack unwinding have the pattern 372e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko // move-exception (move)* (goto)? monitor-exit throw 373e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko // In the currently generated dex bytecode we see these catching a bytecode range including 374e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko // either its own or an identical monitor-exit, http://b/15745363 . This function checks if 375e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko // it's the case for a given monitor-exit and catch block so that we can ignore it. 376e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko // (We don't want to ignore all monitor-exit catches since one could enclose a synchronized 377e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko // block in a try-block and catch the NPE, Error or Throwable and we should let it through; 378e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko // even though a throwing monitor-exit certainly indicates a bytecode error.) 37909ae022f55ab27edf4802baf7a05e76d7dc823a9Razvan A Lupusoru const Instruction* monitor_exit = Instruction::At(current_code_item_->insns_ + monitor_exit_offset); 380e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko DCHECK(monitor_exit->Opcode() == Instruction::MONITOR_EXIT); 381e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko int monitor_reg = monitor_exit->VRegA_11x(); 38209ae022f55ab27edf4802baf7a05e76d7dc823a9Razvan A Lupusoru const Instruction* check_insn = Instruction::At(current_code_item_->insns_ + catch_offset); 383e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko DCHECK(check_insn->Opcode() == Instruction::MOVE_EXCEPTION); 384e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko if (check_insn->VRegA_11x() == monitor_reg) { 385e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko // Unexpected move-exception to the same register. Probably not the pattern we're looking for. 386e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko return false; 387e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko } 388e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko check_insn = check_insn->Next(); 389e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko while (true) { 390e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko int dest = -1; 391e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko bool wide = false; 392e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko switch (check_insn->Opcode()) { 393e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::MOVE_WIDE: 394e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko wide = true; 395fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers FALLTHROUGH_INTENDED; 396e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::MOVE_OBJECT: 397e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::MOVE: 398e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko dest = check_insn->VRegA_12x(); 399e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko break; 400e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko 401e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::MOVE_WIDE_FROM16: 402e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko wide = true; 403fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers FALLTHROUGH_INTENDED; 404e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::MOVE_OBJECT_FROM16: 405e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::MOVE_FROM16: 406e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko dest = check_insn->VRegA_22x(); 407e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko break; 408e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko 409e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::MOVE_WIDE_16: 410e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko wide = true; 411fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers FALLTHROUGH_INTENDED; 412e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::MOVE_OBJECT_16: 413e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::MOVE_16: 414e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko dest = check_insn->VRegA_32x(); 415e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko break; 416e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko 417e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::GOTO: 418e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::GOTO_16: 419e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::GOTO_32: 420e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko check_insn = check_insn->RelativeAt(check_insn->GetTargetOffset()); 421fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers FALLTHROUGH_INTENDED; 422e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko default: 423e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko return check_insn->Opcode() == Instruction::MONITOR_EXIT && 424e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko check_insn->VRegA_11x() == monitor_reg; 425e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko } 426e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko 427e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko if (dest == monitor_reg || (wide && dest + 1 == monitor_reg)) { 428e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko return false; 429e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko } 430e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko 431e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko check_insn = check_insn->Next(); 432e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko } 433e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko} 434e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko 435311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/* Process instructions with the kBranch flag */ 4360d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeBasicBlock* MIRGraph::ProcessCanBranch(BasicBlock* cur_block, MIR* insn, DexOffset cur_offset, 4370d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee int width, int flags, const uint16_t* code_ptr, 4382ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom const uint16_t* code_end) { 4390d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DexOffset target = cur_offset; 440311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee switch (insn->dalvikInsn.opcode) { 441311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::GOTO: 442311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::GOTO_16: 443311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::GOTO_32: 444311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee target += insn->dalvikInsn.vA; 445311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee break; 446311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_EQ: 447311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_NE: 448311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_LT: 449311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_GE: 450311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_GT: 451311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_LE: 452311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cur_block->conditional_branch = true; 453311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee target += insn->dalvikInsn.vC; 454311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee break; 455311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_EQZ: 456311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_NEZ: 457311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_LTZ: 458311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_GEZ: 459311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_GTZ: 460311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_LEZ: 461311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cur_block->conditional_branch = true; 462311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee target += insn->dalvikInsn.vB; 463311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee break; 464311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee default: 465311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee LOG(FATAL) << "Unexpected opcode(" << insn->dalvikInsn.opcode << ") with kBranch set"; 466311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 467b48819db07f9a0992a72173380c24249d7fc648abuzbee CountBranch(target); 4686a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers BasicBlock* taken_block = FindBlock(target, /* create */ true, 469311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* immed_pred_block_p */ &cur_block); 4700d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee cur_block->taken = taken_block->id; 471e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko taken_block->predecessors.push_back(cur_block->id); 472311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 473311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* Always terminate the current block for conditional branches */ 474311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (flags & Instruction::kContinue) { 4752469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler BasicBlock* fallthrough_block = FindBlock(cur_offset + width, 476311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* create */ 477311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee true, 478311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* immed_pred_block_p */ 479311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee &cur_block); 4800d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee cur_block->fall_through = fallthrough_block->id; 481e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko fallthrough_block->predecessors.push_back(cur_block->id); 482311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } else if (code_ptr < code_end) { 4836a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers FindBlock(cur_offset + width, /* create */ true, /* immed_pred_block_p */ nullptr); 484311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 485311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee return cur_block; 486311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 487311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 488311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/* Process instructions with the kSwitch flag */ 48917189ac098b2f156713db1821b49db7b2f018bbebuzbeeBasicBlock* MIRGraph::ProcessCanSwitch(BasicBlock* cur_block, MIR* insn, DexOffset cur_offset, 49017189ac098b2f156713db1821b49db7b2f018bbebuzbee int width, int flags) { 4916a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers UNUSED(flags); 492311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee const uint16_t* switch_data = 493311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee reinterpret_cast<const uint16_t*>(GetCurrentInsns() + cur_offset + insn->dalvikInsn.vB); 494311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int size; 495311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee const int* keyTable; 496311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee const int* target_table; 497311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int i; 498311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int first_key; 499311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 500311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* 501311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Packed switch data format: 502311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * ushort ident = 0x0100 magic value 503311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * ushort size number of entries in the table 504311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * int first_key first (and lowest) switch case value 505311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * int targets[size] branch targets, relative to switch opcode 506311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * 507311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Total size is (4+size*2) 16-bit code units. 508311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 509311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (insn->dalvikInsn.opcode == Instruction::PACKED_SWITCH) { 510311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee DCHECK_EQ(static_cast<int>(switch_data[0]), 511311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee static_cast<int>(Instruction::kPackedSwitchSignature)); 512311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee size = switch_data[1]; 513311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee first_key = switch_data[2] | (switch_data[3] << 16); 514311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee target_table = reinterpret_cast<const int*>(&switch_data[4]); 5158512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler keyTable = NULL; // Make the compiler happy. 516311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* 517311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Sparse switch data format: 518311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * ushort ident = 0x0200 magic value 519311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * ushort size number of entries in the table; > 0 520311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * int keys[size] keys, sorted low-to-high; 32-bit aligned 521311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * int targets[size] branch targets, relative to switch opcode 522311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * 523311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Total size is (2+size*4) 16-bit code units. 524311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 525311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } else { 526311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee DCHECK_EQ(static_cast<int>(switch_data[0]), 527311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee static_cast<int>(Instruction::kSparseSwitchSignature)); 528311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee size = switch_data[1]; 529311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee keyTable = reinterpret_cast<const int*>(&switch_data[2]); 530311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee target_table = reinterpret_cast<const int*>(&switch_data[2 + size*2]); 5318512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler first_key = 0; // To make the compiler happy. 532311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 533311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 5340d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (cur_block->successor_block_list_type != kNotUsed) { 535311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee LOG(FATAL) << "Successor block list already in use: " 5360d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee << static_cast<int>(cur_block->successor_block_list_type); 537311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 5380d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee cur_block->successor_block_list_type = 5390d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee (insn->dalvikInsn.opcode == Instruction::PACKED_SWITCH) ? kPackedSwitch : kSparseSwitch; 540e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko cur_block->successor_blocks.reserve(size); 541311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 542311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (i = 0; i < size; i++) { 5436a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers BasicBlock* case_block = FindBlock(cur_offset + target_table[i], /* create */ true, 5446a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers /* immed_pred_block_p */ &cur_block); 5458512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler SuccessorBlockInfo* successor_block_info = 546f6c4b3ba3825de1dbb3e747a68b809c6cc8eb4dbMathieu Chartier static_cast<SuccessorBlockInfo*>(arena_->Alloc(sizeof(SuccessorBlockInfo), 54783cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko kArenaAllocSuccessor)); 5480d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee successor_block_info->block = case_block->id; 549311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee successor_block_info->key = 550311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee (insn->dalvikInsn.opcode == Instruction::PACKED_SWITCH) ? 551311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee first_key + i : keyTable[i]; 552e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko cur_block->successor_blocks.push_back(successor_block_info); 553e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko case_block->predecessors.push_back(cur_block->id); 554311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 555311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 556311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* Fall-through case */ 5576a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers BasicBlock* fallthrough_block = FindBlock(cur_offset + width, /* create */ true, 5586a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers /* immed_pred_block_p */ nullptr); 5590d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee cur_block->fall_through = fallthrough_block->id; 560e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko fallthrough_block->predecessors.push_back(cur_block->id); 56117189ac098b2f156713db1821b49db7b2f018bbebuzbee return cur_block; 562311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 563311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 564311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/* Process instructions with the kThrow flag */ 5650d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeBasicBlock* MIRGraph::ProcessCanThrow(BasicBlock* cur_block, MIR* insn, DexOffset cur_offset, 5660d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee int width, int flags, ArenaBitVector* try_block_addr, 5672ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom const uint16_t* code_ptr, const uint16_t* code_end) { 5686a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers UNUSED(flags); 569862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee bool in_try_block = try_block_addr->IsBitSet(cur_offset); 57017189ac098b2f156713db1821b49db7b2f018bbebuzbee bool is_throw = (insn->dalvikInsn.opcode == Instruction::THROW); 571311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 572311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* In try block */ 573311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (in_try_block) { 574311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee CatchHandlerIterator iterator(*current_code_item_, cur_offset); 575311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 5760d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (cur_block->successor_block_list_type != kNotUsed) { 577311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee LOG(INFO) << PrettyMethod(cu_->method_idx, *cu_->dex_file); 578311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee LOG(FATAL) << "Successor block list already in use: " 5790d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee << static_cast<int>(cur_block->successor_block_list_type); 580311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 581311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 58202c8cc6d1312a2b55533f02f6369dc7c94672f90Brian Carlstrom for (; iterator.HasNext(); iterator.Next()) { 5836a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers BasicBlock* catch_block = FindBlock(iterator.GetHandlerAddress(), false /* create */, 5846a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers nullptr /* immed_pred_block_p */); 585e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko if (insn->dalvikInsn.opcode == Instruction::MONITOR_EXIT && 586e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko IsBadMonitorExitCatch(insn->offset, catch_block->start_offset)) { 587e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko // Don't allow monitor-exit to catch its own exception, http://b/15745363 . 588e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko continue; 589e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko } 590e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko if (cur_block->successor_block_list_type == kNotUsed) { 591e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko cur_block->successor_block_list_type = kCatch; 592e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko } 593311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee catch_block->catch_entry = true; 594311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (kIsDebugBuild) { 595311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee catches_.insert(catch_block->start_offset); 596311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 5978512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler SuccessorBlockInfo* successor_block_info = reinterpret_cast<SuccessorBlockInfo*> 59883cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko (arena_->Alloc(sizeof(SuccessorBlockInfo), kArenaAllocSuccessor)); 5990d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee successor_block_info->block = catch_block->id; 600311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee successor_block_info->key = iterator.GetHandlerTypeIndex(); 601e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko cur_block->successor_blocks.push_back(successor_block_info); 602e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko catch_block->predecessors.push_back(cur_block->id); 603311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 604e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko in_try_block = (cur_block->successor_block_list_type != kNotUsed); 605e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko } 606e767f6ce3997f7634b26e7651bc7b90c060d3965Vladimir Marko bool build_all_edges = 607e767f6ce3997f7634b26e7651bc7b90c060d3965Vladimir Marko (cu_->disable_opt & (1 << kSuppressExceptionEdges)) || is_throw || in_try_block; 608e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko if (!in_try_block && build_all_edges) { 609e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* eh_block = CreateNewBB(kExceptionHandling); 6100d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee cur_block->taken = eh_block->id; 611311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee eh_block->start_offset = cur_offset; 612e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko eh_block->predecessors.push_back(cur_block->id); 613311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 614311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 61517189ac098b2f156713db1821b49db7b2f018bbebuzbee if (is_throw) { 616311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cur_block->explicit_throw = true; 6172724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee if (code_ptr < code_end) { 6188512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Force creation of new block following THROW via side-effect. 6196a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers FindBlock(cur_offset + width, /* create */ true, /* immed_pred_block_p */ nullptr); 620311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 621311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (!in_try_block) { 622311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee // Don't split a THROW that can't rethrow - we're done. 623311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee return cur_block; 624311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 625311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 626311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 62717189ac098b2f156713db1821b49db7b2f018bbebuzbee if (!build_all_edges) { 62817189ac098b2f156713db1821b49db7b2f018bbebuzbee /* 62917189ac098b2f156713db1821b49db7b2f018bbebuzbee * Even though there is an exception edge here, control cannot return to this 63017189ac098b2f156713db1821b49db7b2f018bbebuzbee * method. Thus, for the purposes of dataflow analysis and optimization, we can 63117189ac098b2f156713db1821b49db7b2f018bbebuzbee * ignore the edge. Doing this reduces compile time, and increases the scope 63217189ac098b2f156713db1821b49db7b2f018bbebuzbee * of the basic-block level optimization pass. 63317189ac098b2f156713db1821b49db7b2f018bbebuzbee */ 63417189ac098b2f156713db1821b49db7b2f018bbebuzbee return cur_block; 63517189ac098b2f156713db1821b49db7b2f018bbebuzbee } 63617189ac098b2f156713db1821b49db7b2f018bbebuzbee 637311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* 638311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Split the potentially-throwing instruction into two parts. 639311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * The first half will be a pseudo-op that captures the exception 640311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * edges and terminates the basic block. It always falls through. 641311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Then, create a new basic block that begins with the throwing instruction 642311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * (minus exceptions). Note: this new basic block must NOT be entered into 643311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * the block_map. If the potentially-throwing instruction is the target of a 644311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * future branch, we need to find the check psuedo half. The new 645311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * basic block containing the work portion of the instruction should 646311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * only be entered via fallthrough from the block containing the 647311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * pseudo exception edge MIR. Note also that this new block is 648311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * not automatically terminated after the work portion, and may 649311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * contain following instructions. 650b48819db07f9a0992a72173380c24249d7fc648abuzbee * 651b48819db07f9a0992a72173380c24249d7fc648abuzbee * Note also that the dex_pc_to_block_map_ entry for the potentially 652b48819db07f9a0992a72173380c24249d7fc648abuzbee * throwing instruction will refer to the original basic block. 653311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 654e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* new_block = CreateNewBB(kDalvikByteCode); 655311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee new_block->start_offset = insn->offset; 6560d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee cur_block->fall_through = new_block->id; 657e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko new_block->predecessors.push_back(cur_block->id); 6583aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler MIR* new_insn = NewMIR(); 659311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee *new_insn = *insn; 66035ba7f3a78d38885ec54e61ed060d2771eeceea7buzbee insn->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpCheck); 6618512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Associate the two halves. 662311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee insn->meta.throw_insn = new_insn; 663cdacac4a8196bdc620185079ec9e886329606f3dJean Christophe Beyler new_block->AppendMIR(new_insn); 664311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee return new_block; 665311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 666311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 667311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/* Parse a Dex method and insert it into the MIRGraph at the current insert point. */ 668311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeevoid MIRGraph::InlineMethod(const DexFile::CodeItem* code_item, uint32_t access_flags, 6698b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers InvokeType invoke_type, uint16_t class_def_idx, 6702ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom uint32_t method_idx, jobject class_loader, const DexFile& dex_file) { 671311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee current_code_item_ = code_item; 672311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee method_stack_.push_back(std::make_pair(current_method_, current_offset_)); 673311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee current_method_ = m_units_.size(); 674311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee current_offset_ = 0; 675311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee // TODO: will need to snapshot stack image and use that as the mir context identification. 676311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee m_units_.push_back(new DexCompilationUnit(cu_, class_loader, Runtime::Current()->GetClassLinker(), 6772730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko dex_file, current_code_item_, class_def_idx, method_idx, access_flags, 6782730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko cu_->compiler_driver->GetVerifiedMethod(&dex_file, method_idx))); 679311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee const uint16_t* code_ptr = current_code_item_->insns_; 680311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee const uint16_t* code_end = 681311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee current_code_item_->insns_ + current_code_item_->insns_size_in_code_units_; 682311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 683311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee // TODO: need to rework expansion of block list & try_block_addr when inlining activated. 684b48819db07f9a0992a72173380c24249d7fc648abuzbee // TUNING: use better estimate of basic blocks for following resize. 685e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko block_list_.reserve(block_list_.size() + current_code_item_->insns_size_in_code_units_); 686e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko dex_pc_to_block_map_.resize(dex_pc_to_block_map_.size() + current_code_item_->insns_size_in_code_units_); 687bd663de599b16229085759366c56e2ed5a1dc7ecbuzbee 688311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee // TODO: replace with explicit resize routine. Using automatic extension side effect for now. 689862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee try_block_addr_->SetBit(current_code_item_->insns_size_in_code_units_); 690862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee try_block_addr_->ClearBit(current_code_item_->insns_size_in_code_units_); 691311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 692311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee // If this is the first method, set up default entry and exit blocks. 693311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (current_method_ == 0) { 694311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee DCHECK(entry_block_ == NULL); 695311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee DCHECK(exit_block_ == NULL); 696ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko DCHECK_EQ(GetNumBlocks(), 0U); 6970d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // Use id 0 to represent a null block. 698e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* null_block = CreateNewBB(kNullBlock); 6990d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DCHECK_EQ(null_block->id, NullBasicBlockId); 7000d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee null_block->hidden = true; 701e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko entry_block_ = CreateNewBB(kEntryBlock); 702e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko exit_block_ = CreateNewBB(kExitBlock); 703311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee // TODO: deprecate all "cu->" fields; move what's left to wherever CompilationUnit is allocated. 704311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cu_->dex_file = &dex_file; 705311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cu_->class_def_idx = class_def_idx; 706311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cu_->method_idx = method_idx; 707311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cu_->access_flags = access_flags; 708311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cu_->invoke_type = invoke_type; 709311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cu_->shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx)); 710311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } else { 711311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee UNIMPLEMENTED(FATAL) << "Nested inlining not implemented."; 712311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* 713311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Will need to manage storage for ins & outs, push prevous state and update 714311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * insert point. 715311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 716311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 717311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 718311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* Current block to record parsed instructions */ 719e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* cur_block = CreateNewBB(kDalvikByteCode); 7200d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DCHECK_EQ(current_offset_, 0U); 721311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cur_block->start_offset = current_offset_; 7220d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // TODO: for inlining support, insert at the insert point rather than entry block. 7230d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee entry_block_->fall_through = cur_block->id; 724e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko cur_block->predecessors.push_back(entry_block_->id); 725311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 7263d73ba2ce682edfaf41f29521bd6039c6499a1c5Vladimir Marko /* Identify code range in try blocks and set up the empty catch blocks */ 727311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee ProcessTryCatchBlocks(); 728311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 7293d73ba2ce682edfaf41f29521bd6039c6499a1c5Vladimir Marko uint64_t merged_df_flags = 0u; 7303d73ba2ce682edfaf41f29521bd6039c6499a1c5Vladimir Marko 731311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* Parse all instructions and put them into containing basic blocks */ 732311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee while (code_ptr < code_end) { 7333aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler MIR *insn = NewMIR(); 734311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee insn->offset = current_offset_; 735311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee insn->m_unit_index = current_method_; 736311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int width = ParseInsn(code_ptr, &insn->dalvikInsn); 737311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee Instruction::Code opcode = insn->dalvikInsn.opcode; 738311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (opcode_count_ != NULL) { 739311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee opcode_count_[static_cast<int>(opcode)]++; 740311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 741311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 742fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler int flags = insn->dalvikInsn.FlagsOf(); 743b1f1d642093418612c0a27ce4203b421bb6eb767buzbee int verify_flags = Instruction::VerifyFlagsOf(insn->dalvikInsn.opcode); 744311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 745cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler uint64_t df_flags = GetDataFlowAttributes(insn); 7463d73ba2ce682edfaf41f29521bd6039c6499a1c5Vladimir Marko merged_df_flags |= df_flags; 747311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 748311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (df_flags & DF_HAS_DEFS) { 749311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee def_count_ += (df_flags & DF_A_WIDE) ? 2 : 1; 750311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 751311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 7521da1e2fceb0030b4b76b43510b1710a9613e0c2ebuzbee if (df_flags & DF_LVN) { 7531da1e2fceb0030b4b76b43510b1710a9613e0c2ebuzbee cur_block->use_lvn = true; // Run local value numbering on this basic block. 7541da1e2fceb0030b4b76b43510b1710a9613e0c2ebuzbee } 7551da1e2fceb0030b4b76b43510b1710a9613e0c2ebuzbee 7568512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Check for inline data block signatures. 7572724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee if (opcode == Instruction::NOP) { 7582724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee // A simple NOP will have a width of 1 at this point, embedded data NOP > 1. 7592724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee if ((width == 1) && ((current_offset_ & 0x1) == 0x1) && ((code_end - code_ptr) > 1)) { 7602724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee // Could be an aligning nop. If an embedded data NOP follows, treat pair as single unit. 7612724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee uint16_t following_raw_instruction = code_ptr[1]; 7622724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee if ((following_raw_instruction == Instruction::kSparseSwitchSignature) || 7632724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee (following_raw_instruction == Instruction::kPackedSwitchSignature) || 7642724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee (following_raw_instruction == Instruction::kArrayDataSignature)) { 7652724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee width += Instruction::At(code_ptr + 1)->SizeInCodeUnits(); 7662724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee } 7672724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee } 7682724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee if (width == 1) { 7692724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee // It is a simple nop - treat normally. 770cdacac4a8196bdc620185079ec9e886329606f3dJean Christophe Beyler cur_block->AppendMIR(insn); 7712724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee } else { 7720d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DCHECK(cur_block->fall_through == NullBasicBlockId); 7730d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DCHECK(cur_block->taken == NullBasicBlockId); 7746489d22a44ea7d135c142ee94925570d0333d5e7buzbee // Unreachable instruction, mark for no continuation and end basic block. 7752724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee flags &= ~Instruction::kContinue; 7766489d22a44ea7d135c142ee94925570d0333d5e7buzbee FindBlock(current_offset_ + width, /* create */ true, /* immed_pred_block_p */ nullptr); 7772724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee } 7782724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee } else { 779cdacac4a8196bdc620185079ec9e886329606f3dJean Christophe Beyler cur_block->AppendMIR(insn); 7802724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee } 7812724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee 782b48819db07f9a0992a72173380c24249d7fc648abuzbee // Associate the starting dex_pc for this opcode with its containing basic block. 783e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko dex_pc_to_block_map_[insn->offset] = cur_block->id; 784b48819db07f9a0992a72173380c24249d7fc648abuzbee 7852724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee code_ptr += width; 7862724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee 787311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (flags & Instruction::kBranch) { 788311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cur_block = ProcessCanBranch(cur_block, insn, current_offset_, 789311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee width, flags, code_ptr, code_end); 790311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } else if (flags & Instruction::kReturn) { 791311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cur_block->terminated_by_return = true; 7920d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee cur_block->fall_through = exit_block_->id; 793e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko exit_block_->predecessors.push_back(cur_block->id); 794311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* 795311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Terminate the current block if there are instructions 796311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * afterwards. 797311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 798311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (code_ptr < code_end) { 799311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* 800311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Create a fallthrough block for real instructions 801311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * (incl. NOP). 802311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 8036a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers FindBlock(current_offset_ + width, /* create */ true, /* immed_pred_block_p */ nullptr); 804311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 805311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } else if (flags & Instruction::kThrow) { 806311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cur_block = ProcessCanThrow(cur_block, insn, current_offset_, width, flags, try_block_addr_, 807311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee code_ptr, code_end); 808311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } else if (flags & Instruction::kSwitch) { 80917189ac098b2f156713db1821b49db7b2f018bbebuzbee cur_block = ProcessCanSwitch(cur_block, insn, current_offset_, width, flags); 810311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 811688e7c5c9f36573dd4da2edd889470d930b0054bAlexei Zavjalov if (verify_flags & Instruction::kVerifyVarArgRange || 812688e7c5c9f36573dd4da2edd889470d930b0054bAlexei Zavjalov verify_flags & Instruction::kVerifyVarArgRangeNonZero) { 813b1f1d642093418612c0a27ce4203b421bb6eb767buzbee /* 814b1f1d642093418612c0a27ce4203b421bb6eb767buzbee * The Quick backend's runtime model includes a gap between a method's 815b1f1d642093418612c0a27ce4203b421bb6eb767buzbee * argument ("in") vregs and the rest of its vregs. Handling a range instruction 816b1f1d642093418612c0a27ce4203b421bb6eb767buzbee * which spans the gap is somewhat complicated, and should not happen 817b1f1d642093418612c0a27ce4203b421bb6eb767buzbee * in normal usage of dx. Punt to the interpreter. 818b1f1d642093418612c0a27ce4203b421bb6eb767buzbee */ 819b1f1d642093418612c0a27ce4203b421bb6eb767buzbee int first_reg_in_range = insn->dalvikInsn.vC; 820b1f1d642093418612c0a27ce4203b421bb6eb767buzbee int last_reg_in_range = first_reg_in_range + insn->dalvikInsn.vA - 1; 821b1f1d642093418612c0a27ce4203b421bb6eb767buzbee if (IsInVReg(first_reg_in_range) != IsInVReg(last_reg_in_range)) { 822b1f1d642093418612c0a27ce4203b421bb6eb767buzbee punt_to_interpreter_ = true; 823b1f1d642093418612c0a27ce4203b421bb6eb767buzbee } 824b1f1d642093418612c0a27ce4203b421bb6eb767buzbee } 825311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee current_offset_ += width; 8266a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers BasicBlock* next_block = FindBlock(current_offset_, /* create */ false, 8276a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers /* immed_pred_block_p */ nullptr); 828311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (next_block) { 829311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* 830311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * The next instruction could be the target of a previously parsed 831311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * forward branch so a block is already created. If the current 832311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * instruction is not an unconditional branch, connect them through 833311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * the fall-through link. 834311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 8350d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DCHECK(cur_block->fall_through == NullBasicBlockId || 8360d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee GetBasicBlock(cur_block->fall_through) == next_block || 8370d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee GetBasicBlock(cur_block->fall_through) == exit_block_); 838311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 8390d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if ((cur_block->fall_through == NullBasicBlockId) && (flags & Instruction::kContinue)) { 8400d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee cur_block->fall_through = next_block->id; 841e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko next_block->predecessors.push_back(cur_block->id); 842311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 843311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cur_block = next_block; 844311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 845311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 8463d73ba2ce682edfaf41f29521bd6039c6499a1c5Vladimir Marko merged_df_flags_ = merged_df_flags; 8475816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko 848311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (cu_->enable_debug & (1 << kDebugDumpCFG)) { 849311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee DumpCFG("/sdcard/1_post_parse_cfg/", true); 850311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 851311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 852311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (cu_->verbose) { 8531fd3346740dfb7f47be9922312b68a4227fada96buzbee DumpMIRGraph(); 854311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 855311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 856311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 8572ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MIRGraph::ShowOpcodeStats() { 858311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee DCHECK(opcode_count_ != NULL); 859311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee LOG(INFO) << "Opcode Count"; 860311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (int i = 0; i < kNumPackedOpcodes; i++) { 861311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (opcode_count_[i] != 0) { 862311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee LOG(INFO) << "-C- " << Instruction::Name(static_cast<Instruction::Code>(i)) 863311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee << " " << opcode_count_[i]; 864311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 865311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 866311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 867311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 868cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyleruint64_t MIRGraph::GetDataFlowAttributes(Instruction::Code opcode) { 869cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler DCHECK_LT((size_t) opcode, (sizeof(oat_data_flow_attributes_) / sizeof(oat_data_flow_attributes_[0]))); 870cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler return oat_data_flow_attributes_[opcode]; 871cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler} 872cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler 873cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyleruint64_t MIRGraph::GetDataFlowAttributes(MIR* mir) { 874cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler DCHECK(mir != nullptr); 875cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler Instruction::Code opcode = mir->dalvikInsn.opcode; 876cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler return GetDataFlowAttributes(opcode); 877cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler} 878cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler 879311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee// TODO: use a configurable base prefix, and adjust callers to supply pass name. 880311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/* Dump the CFG into a DOT graph */ 881d0a515562772d7c637160e8779c4f253ee169c3aJean Christophe Beylervoid MIRGraph::DumpCFG(const char* dir_prefix, bool all_blocks, const char *suffix) { 882311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee FILE* file; 883a8869e60d93ba9eed36a5b53553b7609f58fc05bJean Christophe Beyler static AtomicInteger cnt(0); 884a8869e60d93ba9eed36a5b53553b7609f58fc05bJean Christophe Beyler 885a8869e60d93ba9eed36a5b53553b7609f58fc05bJean Christophe Beyler // Increment counter to get a unique file number. 886a8869e60d93ba9eed36a5b53553b7609f58fc05bJean Christophe Beyler cnt++; 887a8869e60d93ba9eed36a5b53553b7609f58fc05bJean Christophe Beyler 888311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee std::string fname(PrettyMethod(cu_->method_idx, *cu_->dex_file)); 889311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee ReplaceSpecialChars(fname); 890a8869e60d93ba9eed36a5b53553b7609f58fc05bJean Christophe Beyler fname = StringPrintf("%s%s%x%s_%d.dot", dir_prefix, fname.c_str(), 891d0a515562772d7c637160e8779c4f253ee169c3aJean Christophe Beyler GetBasicBlock(GetEntryBlock()->fall_through)->start_offset, 892a8869e60d93ba9eed36a5b53553b7609f58fc05bJean Christophe Beyler suffix == nullptr ? "" : suffix, 893a8869e60d93ba9eed36a5b53553b7609f58fc05bJean Christophe Beyler cnt.LoadRelaxed()); 894311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee file = fopen(fname.c_str(), "w"); 895311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (file == NULL) { 896311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee return; 897311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 898311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, "digraph G {\n"); 899311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 900311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " rankdir=TB\n"); 901311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 902311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int num_blocks = all_blocks ? GetNumBlocks() : num_reachable_blocks_; 903311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int idx; 904311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 905311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (idx = 0; idx < num_blocks; idx++) { 906e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko int block_idx = all_blocks ? idx : dfs_order_[idx]; 9078512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler BasicBlock* bb = GetBasicBlock(block_idx); 90825bc279080a56546b0f8a33342a853b2778eed0dRazvan A Lupusoru if (bb == NULL) continue; 909311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (bb->block_type == kDead) continue; 910a8869e60d93ba9eed36a5b53553b7609f58fc05bJean Christophe Beyler if (bb->hidden) continue; 911311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (bb->block_type == kEntryBlock) { 912311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " entry_%d [shape=Mdiamond];\n", bb->id); 913311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } else if (bb->block_type == kExitBlock) { 914311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " exit_%d [shape=Mdiamond];\n", bb->id); 915311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } else if (bb->block_type == kDalvikByteCode) { 916311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " block%04x_%d [shape=record,label = \"{ \\\n", 917311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bb->start_offset, bb->id); 9188512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler const MIR* mir; 919311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " {block id %d\\l}%s\\\n", bb->id, 920311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bb->first_mir_insn ? " | " : " "); 921311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (mir = bb->first_mir_insn; mir; mir = mir->next) { 922311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int opcode = mir->dalvikInsn.opcode; 923e0951144d71a4791a5319ec507d84fce373018e0Razvan A Lupusoru fprintf(file, " {%04x %s %s %s %s %s %s %s %s %s\\l}%s\\\n", mir->offset, 924d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell mir->ssa_rep ? GetDalvikDisassembly(mir) : 9252ab40eb3c23559205ac7b9b039bd749458e8a761Jean Christophe Beyler !MIR::DecodedInstruction::IsPseudoMirOp(opcode) ? 9262ab40eb3c23559205ac7b9b039bd749458e8a761Jean Christophe Beyler Instruction::Name(mir->dalvikInsn.opcode) : 927d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell extended_mir_op_names_[opcode - kMirOpFirst], 928d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell (mir->optimization_flags & MIR_IGNORE_RANGE_CHECK) != 0 ? " no_rangecheck" : " ", 929d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell (mir->optimization_flags & MIR_IGNORE_NULL_CHECK) != 0 ? " no_nullcheck" : " ", 93060bfe7b3e8f00f0a8ef3f5d8716adfdf86b71f43Udayan Banerji (mir->optimization_flags & MIR_IGNORE_SUSPEND_CHECK) != 0 ? " no_suspendcheck" : " ", 931b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler (mir->optimization_flags & MIR_STORE_NON_TEMPORAL) != 0 ? " non_temporal" : " ", 9321500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru (mir->optimization_flags & MIR_CALLEE) != 0 ? " inlined" : " ", 93366c6d7bdfdd535e6ecf4461bba3804f1a7794fcdVladimir Marko (mir->optimization_flags & MIR_CLASS_IS_INITIALIZED) != 0 ? " cl_inited" : " ", 93466c6d7bdfdd535e6ecf4461bba3804f1a7794fcdVladimir Marko (mir->optimization_flags & MIR_CLASS_IS_IN_DEX_CACHE) != 0 ? " cl_in_cache" : " ", 935e0951144d71a4791a5319ec507d84fce373018e0Razvan A Lupusoru (mir->optimization_flags & MIR_IGNORE_DIV_ZERO_CHECK) != 0 ? " no_div_check" : " ", 936d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell mir->next ? " | " : " "); 937311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 938311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " }\"];\n\n"); 939311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } else if (bb->block_type == kExceptionHandling) { 940311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee char block_name[BLOCK_NAME_LEN]; 941311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 942311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee GetBlockName(bb, block_name); 943311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " %s [shape=invhouse];\n", block_name); 944311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 945311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 946311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee char block_name1[BLOCK_NAME_LEN], block_name2[BLOCK_NAME_LEN]; 947311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 9480d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (bb->taken != NullBasicBlockId) { 949311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee GetBlockName(bb, block_name1); 9500d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee GetBlockName(GetBasicBlock(bb->taken), block_name2); 951311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " %s:s -> %s:n [style=dotted]\n", 952311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee block_name1, block_name2); 953311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 9540d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (bb->fall_through != NullBasicBlockId) { 955311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee GetBlockName(bb, block_name1); 9560d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee GetBlockName(GetBasicBlock(bb->fall_through), block_name2); 957311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " %s:s -> %s:n\n", block_name1, block_name2); 958311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 959311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 9600d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (bb->successor_block_list_type != kNotUsed) { 961311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " succ%04x_%d [shape=%s,label = \"{ \\\n", 962311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bb->start_offset, bb->id, 9630d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee (bb->successor_block_list_type == kCatch) ? "Mrecord" : "record"); 964311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 965e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko int last_succ_id = static_cast<int>(bb->successor_blocks.size() - 1u); 966311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int succ_id = 0; 967e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (SuccessorBlockInfo* successor_block_info : bb->successor_blocks) { 9688512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler BasicBlock* dest_block = GetBasicBlock(successor_block_info->block); 969311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " {<f%d> %04x: %04x\\l}%s\\\n", 970e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko succ_id, 971311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee successor_block_info->key, 972311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee dest_block->start_offset, 973e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko (succ_id != last_succ_id) ? " | " : " "); 974e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko ++succ_id; 975311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 976311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " }\"];\n\n"); 977311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 978311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee GetBlockName(bb, block_name1); 979311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " %s:s -> succ%04x_%d:n [style=dashed]\n", 980311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee block_name1, bb->start_offset, bb->id); 981311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 98225bc279080a56546b0f8a33342a853b2778eed0dRazvan A Lupusoru // Link the successor pseudo-block with all of its potential targets. 98325bc279080a56546b0f8a33342a853b2778eed0dRazvan A Lupusoru succ_id = 0; 984e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (SuccessorBlockInfo* successor_block_info : bb->successor_blocks) { 98525bc279080a56546b0f8a33342a853b2778eed0dRazvan A Lupusoru BasicBlock* dest_block = GetBasicBlock(successor_block_info->block); 986311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 98725bc279080a56546b0f8a33342a853b2778eed0dRazvan A Lupusoru GetBlockName(dest_block, block_name2); 98825bc279080a56546b0f8a33342a853b2778eed0dRazvan A Lupusoru fprintf(file, " succ%04x_%d:f%d:e -> %s:n\n", bb->start_offset, 98925bc279080a56546b0f8a33342a853b2778eed0dRazvan A Lupusoru bb->id, succ_id++, block_name2); 990311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 991311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 992311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, "\n"); 993311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 994311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (cu_->verbose) { 995311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* Display the dominator tree */ 996311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee GetBlockName(bb, block_name1); 997311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " cfg%s [label=\"%s\", shape=none];\n", 998311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee block_name1, block_name1); 999311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (bb->i_dom) { 10000d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee GetBlockName(GetBasicBlock(bb->i_dom), block_name2); 1001311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " cfg%s:s -> cfg%s:n\n\n", block_name2, block_name1); 1002311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 1003311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 1004311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 1005311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, "}\n"); 1006311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fclose(file); 1007311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 1008311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 10093aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler/* Insert an MIR instruction to the end of a basic block. */ 1010cdacac4a8196bdc620185079ec9e886329606f3dJean Christophe Beylervoid BasicBlock::AppendMIR(MIR* mir) { 10118512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Insert it after the last MIR. 10128512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler InsertMIRListAfter(last_mir_insn, mir, mir); 10138512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 10148512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 10158512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylervoid BasicBlock::AppendMIRList(MIR* first_list_mir, MIR* last_list_mir) { 10168512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Insert it after the last MIR. 10178512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler InsertMIRListAfter(last_mir_insn, first_list_mir, last_list_mir); 10188512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 10198512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 10208512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylervoid BasicBlock::AppendMIRList(const std::vector<MIR*>& insns) { 10218512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler for (std::vector<MIR*>::const_iterator it = insns.begin(); it != insns.end(); it++) { 10228512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler MIR* new_mir = *it; 10238512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 10248512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Add a copy of each MIR. 10258512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler InsertMIRListAfter(last_mir_insn, new_mir, new_mir); 10268512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 10278512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 10288512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 10298512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler/* Insert a MIR instruction after the specified MIR. */ 10308512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylervoid BasicBlock::InsertMIRAfter(MIR* current_mir, MIR* new_mir) { 10318512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler InsertMIRListAfter(current_mir, new_mir, new_mir); 10328512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 10338512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 10348512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylervoid BasicBlock::InsertMIRListAfter(MIR* insert_after, MIR* first_list_mir, MIR* last_list_mir) { 10358512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // If no MIR, we are done. 10368512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (first_list_mir == nullptr || last_list_mir == nullptr) { 10378512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return; 10388512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 10398512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 10408512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // If insert_after is null, assume BB is empty. 10418512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (insert_after == nullptr) { 10428512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler first_mir_insn = first_list_mir; 10438512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_mir_insn = last_list_mir; 10448512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_list_mir->next = nullptr; 10451fd3346740dfb7f47be9922312b68a4227fada96buzbee } else { 10468512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler MIR* after_list = insert_after->next; 10478512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler insert_after->next = first_list_mir; 10488512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_list_mir->next = after_list; 10498512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (after_list == nullptr) { 10508512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_mir_insn = last_list_mir; 10518512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 10521fd3346740dfb7f47be9922312b68a4227fada96buzbee } 10533aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 10548512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Set this BB to be the basic block of the MIRs. 10558512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler MIR* last = last_list_mir->next; 10568512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler for (MIR* mir = first_list_mir; mir != last; mir = mir->next) { 10578512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler mir->bb = id; 10588512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 10591fd3346740dfb7f47be9922312b68a4227fada96buzbee} 10601fd3346740dfb7f47be9922312b68a4227fada96buzbee 10613aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler/* Insert an MIR instruction to the head of a basic block. */ 1062cdacac4a8196bdc620185079ec9e886329606f3dJean Christophe Beylervoid BasicBlock::PrependMIR(MIR* mir) { 10638512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler InsertMIRListBefore(first_mir_insn, mir, mir); 10648512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 10653aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 10668512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylervoid BasicBlock::PrependMIRList(MIR* first_list_mir, MIR* last_list_mir) { 10678512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Insert it before the first MIR. 10688512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler InsertMIRListBefore(first_mir_insn, first_list_mir, last_list_mir); 10691fd3346740dfb7f47be9922312b68a4227fada96buzbee} 10701fd3346740dfb7f47be9922312b68a4227fada96buzbee 10718512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylervoid BasicBlock::PrependMIRList(const std::vector<MIR*>& to_add) { 10728512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler for (std::vector<MIR*>::const_iterator it = to_add.begin(); it != to_add.end(); it++) { 10738512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler MIR* mir = *it; 10741fd3346740dfb7f47be9922312b68a4227fada96buzbee 10758512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler InsertMIRListBefore(first_mir_insn, mir, mir); 10761fd3346740dfb7f47be9922312b68a4227fada96buzbee } 10778512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 10783aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 10798512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler/* Insert a MIR instruction before the specified MIR. */ 10808512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylervoid BasicBlock::InsertMIRBefore(MIR* current_mir, MIR* new_mir) { 10818512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Insert as a single element list. 10828512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return InsertMIRListBefore(current_mir, new_mir, new_mir); 10833aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler} 10843aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 10853aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe BeylerMIR* BasicBlock::FindPreviousMIR(MIR* mir) { 10863aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler MIR* current = first_mir_insn; 10873aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 10883aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler while (current != nullptr) { 10893aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler MIR* next = current->next; 10903aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 10913aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler if (next == mir) { 10923aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler return current; 10933aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler } 10943aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 10953aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler current = next; 10963aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler } 10973aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 10983aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler return nullptr; 10993aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler} 11003aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 11018512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylervoid BasicBlock::InsertMIRListBefore(MIR* insert_before, MIR* first_list_mir, MIR* last_list_mir) { 11028512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // If no MIR, we are done. 11038512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (first_list_mir == nullptr || last_list_mir == nullptr) { 11048512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return; 11058512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 11068512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 11078512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // If insert_before is null, assume BB is empty. 11088512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (insert_before == nullptr) { 11098512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler first_mir_insn = first_list_mir; 11108512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_mir_insn = last_list_mir; 11118512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_list_mir->next = nullptr; 11128512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } else { 11138512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (first_mir_insn == insert_before) { 11148512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_list_mir->next = first_mir_insn; 11158512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler first_mir_insn = first_list_mir; 11168512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } else { 11178512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Find the preceding MIR. 11188512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler MIR* before_list = FindPreviousMIR(insert_before); 11198512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler DCHECK(before_list != nullptr); 11208512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler before_list->next = first_list_mir; 11218512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_list_mir->next = insert_before; 11228512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 11238512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 11248512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 11258512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Set this BB to be the basic block of the MIRs. 11268512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler for (MIR* mir = first_list_mir; mir != last_list_mir->next; mir = mir->next) { 11278512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler mir->bb = id; 11283aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler } 11298512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 11308512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 11318512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylerbool BasicBlock::RemoveMIR(MIR* mir) { 11328512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Remove as a single element list. 11338512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return RemoveMIRList(mir, mir); 11348512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 11358512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 11368512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylerbool BasicBlock::RemoveMIRList(MIR* first_list_mir, MIR* last_list_mir) { 11378512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (first_list_mir == nullptr) { 11388512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return false; 11398512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 11408512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 11418512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Try to find the MIR. 11428512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler MIR* before_list = nullptr; 11438512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler MIR* after_list = nullptr; 11443aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 11458512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // If we are removing from the beginning of the MIR list. 11468512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (first_mir_insn == first_list_mir) { 11478512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler before_list = nullptr; 11488512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } else { 11498512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler before_list = FindPreviousMIR(first_list_mir); 11508512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (before_list == nullptr) { 11518512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // We did not find the mir. 11528512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return false; 11538512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 11548512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 11558512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 1156a4307aca310aac0ac62dcb5435daa02b1f950558Jean Christophe Beyler // Remove the BB information and also find the after_list. 1157590c6a4ded1deb378baa253c86070d8eeffdc820Chao-ying Fu for (MIR* mir = first_list_mir; mir != last_list_mir->next; mir = mir->next) { 11588512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler mir->bb = NullBasicBlockId; 11598512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 11608512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 11618512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler after_list = last_list_mir->next; 11628512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 1163a4307aca310aac0ac62dcb5435daa02b1f950558Jean Christophe Beyler // If there is nothing before the list, after_list is the first_mir. 11648512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (before_list == nullptr) { 11658512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler first_mir_insn = after_list; 1166a4307aca310aac0ac62dcb5435daa02b1f950558Jean Christophe Beyler } else { 1167a4307aca310aac0ac62dcb5435daa02b1f950558Jean Christophe Beyler before_list->next = after_list; 11688512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 11693aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 1170a4307aca310aac0ac62dcb5435daa02b1f950558Jean Christophe Beyler // If there is nothing after the list, before_list is last_mir. 11718512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (after_list == nullptr) { 11728512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_mir_insn = before_list; 11733aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler } 11748512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 11758512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return true; 11761fd3346740dfb7f47be9922312b68a4227fada96buzbee} 11771fd3346740dfb7f47be9922312b68a4227fada96buzbee 117826e7d454b9924f3673b075b05e4c604ad658a062Vladimir MarkoMIR* BasicBlock::GetFirstNonPhiInsn() { 117926e7d454b9924f3673b075b05e4c604ad658a062Vladimir Marko MIR* mir = first_mir_insn; 118026e7d454b9924f3673b075b05e4c604ad658a062Vladimir Marko while (mir != nullptr && static_cast<int>(mir->dalvikInsn.opcode) == kMirOpPhi) { 118126e7d454b9924f3673b075b05e4c604ad658a062Vladimir Marko mir = mir->next; 118226e7d454b9924f3673b075b05e4c604ad658a062Vladimir Marko } 118326e7d454b9924f3673b075b05e4c604ad658a062Vladimir Marko return mir; 118426e7d454b9924f3673b075b05e4c604ad658a062Vladimir Marko} 118526e7d454b9924f3673b075b05e4c604ad658a062Vladimir Marko 1186cdacac4a8196bdc620185079ec9e886329606f3dJean Christophe BeylerMIR* BasicBlock::GetNextUnconditionalMir(MIRGraph* mir_graph, MIR* current) { 11873bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru MIR* next_mir = nullptr; 11883bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru 11893bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru if (current != nullptr) { 11903bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru next_mir = current->next; 11913bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru } 11923bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru 11933bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru if (next_mir == nullptr) { 11943bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru // Only look for next MIR that follows unconditionally. 1195cdacac4a8196bdc620185079ec9e886329606f3dJean Christophe Beyler if ((taken == NullBasicBlockId) && (fall_through != NullBasicBlockId)) { 1196cdacac4a8196bdc620185079ec9e886329606f3dJean Christophe Beyler next_mir = mir_graph->GetBasicBlock(fall_through)->first_mir_insn; 11973bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru } 11983bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru } 11993bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru 12003bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru return next_mir; 12013bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru} 12023bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru 12031500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusorustatic void FillTypeSizeString(uint32_t type_size, std::string* decoded_mir) { 12041500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru DCHECK(decoded_mir != nullptr); 12051500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru OpSize type = static_cast<OpSize>(type_size >> 16); 12061500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru uint16_t vect_size = (type_size & 0xFFFF); 12071500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru 12081500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru // Now print the type and vector size. 12091500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru std::stringstream ss; 12101500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru ss << " (type:"; 12111500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru ss << type; 12121500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru ss << " vectsize:"; 12131500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru ss << vect_size; 12141500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru ss << ")"; 12151500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru 12161500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(ss.str()); 12171500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru} 12181500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru 12191500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoruvoid MIRGraph::DisassembleExtendedInstr(const MIR* mir, std::string* decoded_mir) { 12201500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru DCHECK(decoded_mir != nullptr); 12211500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru int opcode = mir->dalvikInsn.opcode; 12221500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru SSARepresentation* ssa_rep = mir->ssa_rep; 12231500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru int defs = (ssa_rep != nullptr) ? ssa_rep->num_defs : 0; 12241500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru int uses = (ssa_rep != nullptr) ? ssa_rep->num_uses : 0; 12251500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru 1226f41b92c7a2fcdd411b9edd7070e4729ea18e0ba6Vladimir if (opcode < kMirOpFirst) { 1227f41b92c7a2fcdd411b9edd7070e4729ea18e0ba6Vladimir return; // It is not an extended instruction. 1228f41b92c7a2fcdd411b9edd7070e4729ea18e0ba6Vladimir } 1229f41b92c7a2fcdd411b9edd7070e4729ea18e0ba6Vladimir 12301500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(extended_mir_op_names_[opcode - kMirOpFirst]); 12311500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru 12321500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru switch (opcode) { 12331500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPhi: { 12341500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (defs > 0 && uses > 0) { 12351500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru BasicBlockId* incoming = mir->meta.phi_incoming; 12361500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" %s = (%s", 12371500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru GetSSANameWithConst(ssa_rep->defs[0], true).c_str(), 12381500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru GetSSANameWithConst(ssa_rep->uses[0], true).c_str())); 12391500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(":%d", incoming[0])); 12401500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru for (int i = 1; i < uses; i++) { 12411500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(", %s:%d", GetSSANameWithConst(ssa_rep->uses[i], true).c_str(), incoming[i])); 12421500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 12431500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(")"); 12441500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 12451500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 12461500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 12471500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpCopy: 12481500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (ssa_rep != nullptr) { 12491500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(" "); 12501500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[0], false)); 12511500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (defs > 1) { 12521500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(", "); 12531500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[1], false)); 12541500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 12551500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(" = "); 12561500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->uses[0], false)); 12571500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (uses > 1) { 12581500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(", "); 12591500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->uses[1], false)); 12601500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 12611500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } else { 12621500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" v%d = v%d", mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 12631500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 12641500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 12651500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpFusedCmplFloat: 12661500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpFusedCmpgFloat: 12671500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpFusedCmplDouble: 12681500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpFusedCmpgDouble: 12691500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpFusedCmpLong: 12701500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (ssa_rep != nullptr) { 12711500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(" "); 12721500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->uses[0], false)); 12731500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru for (int i = 1; i < uses; i++) { 12741500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(", "); 12751500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->uses[i], false)); 12761500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 12771500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } else { 12781500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" v%d, v%d", mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 12791500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 12801500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 12811500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpMoveVector: 12821500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 12831500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 12841500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 12851500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedAddition: 12861500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d + vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 12871500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 12881500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 12891500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedMultiply: 12901500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d * vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 12911500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 12921500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 12931500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedSubtract: 12941500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d - vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 12951500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 12961500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 12971500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedAnd: 12981500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d & vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 12991500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 13001500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13011500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedOr: 13021500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d \\| vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 13031500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 13041500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13051500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedXor: 13061500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d ^ vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 13071500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 13081500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13091500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedShiftLeft: 13101500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d \\<\\< %d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 13111500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 13121500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13131500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedUnsignedShiftRight: 13141500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d \\>\\>\\> %d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 13151500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 13161500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13171500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedSignedShiftRight: 13181500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d \\>\\> %d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 13191500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 13201500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13211500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpConstVector: 13221500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = %x, %x, %x, %x", mir->dalvikInsn.vA, mir->dalvikInsn.arg[0], 13231500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru mir->dalvikInsn.arg[1], mir->dalvikInsn.arg[2], mir->dalvikInsn.arg[3])); 13241500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13251500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedSet: 13261500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (ssa_rep != nullptr) { 13271500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = %s", mir->dalvikInsn.vA, 13281500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru GetSSANameWithConst(ssa_rep->uses[0], false).c_str())); 13291500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (uses > 1) { 13301500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(", "); 13311500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->uses[1], false)); 13321500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 13331500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } else { 13341500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = v%d", mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 13351500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 13361500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 13371500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13381500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedAddReduce: 13391500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (ssa_rep != nullptr) { 13401500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(" "); 13411500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[0], false)); 13421500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (defs > 1) { 13431500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(", "); 13441500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[1], false)); 13451500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 13461500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" = vect%d + %s", mir->dalvikInsn.vB, 13471500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru GetSSANameWithConst(ssa_rep->uses[0], false).c_str())); 13481500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (uses > 1) { 13491500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(", "); 13501500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->uses[1], false)); 13511500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 13521500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } else { 13531500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf("v%d = vect%d + v%d", mir->dalvikInsn.vA, mir->dalvikInsn.vB, mir->dalvikInsn.vA)); 13541500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 13551500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 13561500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13571500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedReduce: 13581500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (ssa_rep != nullptr) { 13591500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(" "); 13601500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[0], false)); 13611500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (defs > 1) { 13621500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(", "); 13631500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[1], false)); 13641500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 1365b72c723bfb21e05cb9b0a7999db805df93fcaee8Razvan A Lupusoru decoded_mir->append(StringPrintf(" = vect%d (extr_idx:%d)", mir->dalvikInsn.vB, mir->dalvikInsn.arg[0])); 13661500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } else { 1367b72c723bfb21e05cb9b0a7999db805df93fcaee8Razvan A Lupusoru decoded_mir->append(StringPrintf(" v%d = vect%d (extr_idx:%d)", mir->dalvikInsn.vA, 1368b72c723bfb21e05cb9b0a7999db805df93fcaee8Razvan A Lupusoru mir->dalvikInsn.vB, mir->dalvikInsn.arg[0])); 13691500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 13701500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 13711500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13721500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpReserveVectorRegisters: 13731500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpReturnVectorRegisters: 13741500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d - vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 13751500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13761500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpMemBarrier: { 13771500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(" type:"); 13781500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru std::stringstream ss; 13791500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru ss << static_cast<MemBarrierKind>(mir->dalvikInsn.vA); 13801500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(ss.str()); 13811500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13821500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 1383b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A case kMirOpPackedArrayGet: 1384b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A case kMirOpPackedArrayPut: 1385b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A decoded_mir->append(StringPrintf(" vect%d", mir->dalvikInsn.vA)); 1386b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A if (ssa_rep != nullptr) { 1387b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A decoded_mir->append(StringPrintf(", %s[%s]", 1388b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A GetSSANameWithConst(ssa_rep->uses[0], false).c_str(), 1389b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A GetSSANameWithConst(ssa_rep->uses[1], false).c_str())); 1390b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A } else { 1391b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A decoded_mir->append(StringPrintf(", v%d[v%d]", mir->dalvikInsn.vB, mir->dalvikInsn.vC)); 1392b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A } 1393b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A FillTypeSizeString(mir->dalvikInsn.arg[0], decoded_mir); 1394b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A break; 1395a262f7707330dccfb50af6345813083182b61043Ningsheng Jian case kMirOpMaddInt: 1396a262f7707330dccfb50af6345813083182b61043Ningsheng Jian case kMirOpMsubInt: 1397a262f7707330dccfb50af6345813083182b61043Ningsheng Jian case kMirOpMaddLong: 1398a262f7707330dccfb50af6345813083182b61043Ningsheng Jian case kMirOpMsubLong: 1399a262f7707330dccfb50af6345813083182b61043Ningsheng Jian if (ssa_rep != nullptr) { 1400a262f7707330dccfb50af6345813083182b61043Ningsheng Jian decoded_mir->append(" "); 1401a262f7707330dccfb50af6345813083182b61043Ningsheng Jian decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[0], false)); 1402a262f7707330dccfb50af6345813083182b61043Ningsheng Jian if (defs > 1) { 1403a262f7707330dccfb50af6345813083182b61043Ningsheng Jian decoded_mir->append(", "); 1404a262f7707330dccfb50af6345813083182b61043Ningsheng Jian decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[1], false)); 1405a262f7707330dccfb50af6345813083182b61043Ningsheng Jian } 1406a262f7707330dccfb50af6345813083182b61043Ningsheng Jian for (int i = 0; i < uses; i++) { 1407a262f7707330dccfb50af6345813083182b61043Ningsheng Jian decoded_mir->append(", "); 1408a262f7707330dccfb50af6345813083182b61043Ningsheng Jian decoded_mir->append(GetSSANameWithConst(ssa_rep->uses[i], false)); 1409a262f7707330dccfb50af6345813083182b61043Ningsheng Jian } 1410a262f7707330dccfb50af6345813083182b61043Ningsheng Jian } else { 1411a262f7707330dccfb50af6345813083182b61043Ningsheng Jian decoded_mir->append(StringPrintf(" v%d, v%d, v%d, v%d", 1412a262f7707330dccfb50af6345813083182b61043Ningsheng Jian mir->dalvikInsn.vA, mir->dalvikInsn.vB, 1413a262f7707330dccfb50af6345813083182b61043Ningsheng Jian mir->dalvikInsn.vC, mir->dalvikInsn.arg[0])); 1414a262f7707330dccfb50af6345813083182b61043Ningsheng Jian } 1415a262f7707330dccfb50af6345813083182b61043Ningsheng Jian break; 14161500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru default: 14171500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 14181500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 14191500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru} 14201500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru 14212ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromchar* MIRGraph::GetDalvikDisassembly(const MIR* mir) { 142229a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers MIR::DecodedInstruction insn = mir->dalvikInsn; 14231fd3346740dfb7f47be9922312b68a4227fada96buzbee std::string str; 14241fd3346740dfb7f47be9922312b68a4227fada96buzbee int flags = 0; 14251fd3346740dfb7f47be9922312b68a4227fada96buzbee int opcode = insn.opcode; 14261fd3346740dfb7f47be9922312b68a4227fada96buzbee char* ret; 14271fd3346740dfb7f47be9922312b68a4227fada96buzbee bool nop = false; 14281fd3346740dfb7f47be9922312b68a4227fada96buzbee SSARepresentation* ssa_rep = mir->ssa_rep; 14298512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler Instruction::Format dalvik_format = Instruction::k10x; // Default to no-operand format. 14301fd3346740dfb7f47be9922312b68a4227fada96buzbee 14311500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru // Handle special cases that recover the original dalvik instruction. 14321fd3346740dfb7f47be9922312b68a4227fada96buzbee if ((opcode == kMirOpCheck) || (opcode == kMirOpCheckPart2)) { 14331fd3346740dfb7f47be9922312b68a4227fada96buzbee str.append(extended_mir_op_names_[opcode - kMirOpFirst]); 14341fd3346740dfb7f47be9922312b68a4227fada96buzbee str.append(": "); 14358512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Recover the original Dex instruction. 14361fd3346740dfb7f47be9922312b68a4227fada96buzbee insn = mir->meta.throw_insn->dalvikInsn; 14371fd3346740dfb7f47be9922312b68a4227fada96buzbee ssa_rep = mir->meta.throw_insn->ssa_rep; 14381fd3346740dfb7f47be9922312b68a4227fada96buzbee opcode = insn.opcode; 14391fd3346740dfb7f47be9922312b68a4227fada96buzbee } else if (opcode == kMirOpNop) { 14401fd3346740dfb7f47be9922312b68a4227fada96buzbee str.append("["); 1441750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru if (mir->offset < current_code_item_->insns_size_in_code_units_) { 1442750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru // Recover original opcode. 1443750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru insn.opcode = Instruction::At(current_code_item_->insns_ + mir->offset)->Opcode(); 1444750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru opcode = insn.opcode; 1445750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru } 14461fd3346740dfb7f47be9922312b68a4227fada96buzbee nop = true; 14471fd3346740dfb7f47be9922312b68a4227fada96buzbee } 14480f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov int defs = (ssa_rep != NULL) ? ssa_rep->num_defs : 0; 14490f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov int uses = (ssa_rep != NULL) ? ssa_rep->num_uses : 0; 14501fd3346740dfb7f47be9922312b68a4227fada96buzbee 14512ab40eb3c23559205ac7b9b039bd749458e8a761Jean Christophe Beyler if (MIR::DecodedInstruction::IsPseudoMirOp(opcode)) { 14521500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru // Note that this does not check the MIR's opcode in all cases. In cases where it 14531500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru // recovered dalvik instruction, it uses opcode of that instead of the extended one. 14541500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru DisassembleExtendedInstr(mir, &str); 14551fd3346740dfb7f47be9922312b68a4227fada96buzbee } else { 14561fd3346740dfb7f47be9922312b68a4227fada96buzbee dalvik_format = Instruction::FormatOf(insn.opcode); 1457fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler flags = insn.FlagsOf(); 14581fd3346740dfb7f47be9922312b68a4227fada96buzbee str.append(Instruction::Name(insn.opcode)); 14591fd3346740dfb7f47be9922312b68a4227fada96buzbee 14608512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // For invokes-style formats, treat wide regs as a pair of singles. 14611fd3346740dfb7f47be9922312b68a4227fada96buzbee bool show_singles = ((dalvik_format == Instruction::k35c) || 14621fd3346740dfb7f47be9922312b68a4227fada96buzbee (dalvik_format == Instruction::k3rc)); 14631fd3346740dfb7f47be9922312b68a4227fada96buzbee if (defs != 0) { 14641500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(" "); 14651500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(GetSSANameWithConst(ssa_rep->defs[0], false)); 14661500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (defs > 1) { 14671500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(", "); 14681500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(GetSSANameWithConst(ssa_rep->defs[1], false)); 14691500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 14701fd3346740dfb7f47be9922312b68a4227fada96buzbee if (uses != 0) { 14711fd3346740dfb7f47be9922312b68a4227fada96buzbee str.append(", "); 14721fd3346740dfb7f47be9922312b68a4227fada96buzbee } 14731fd3346740dfb7f47be9922312b68a4227fada96buzbee } 14741fd3346740dfb7f47be9922312b68a4227fada96buzbee for (int i = 0; i < uses; i++) { 14751500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(" "); 14761500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(GetSSANameWithConst(ssa_rep->uses[i], show_singles)); 14771fd3346740dfb7f47be9922312b68a4227fada96buzbee if (!show_singles && (reg_location_ != NULL) && reg_location_[i].wide) { 14781fd3346740dfb7f47be9922312b68a4227fada96buzbee // For the listing, skip the high sreg. 14791fd3346740dfb7f47be9922312b68a4227fada96buzbee i++; 14801fd3346740dfb7f47be9922312b68a4227fada96buzbee } 14811500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (i != (uses - 1)) { 14821fd3346740dfb7f47be9922312b68a4227fada96buzbee str.append(","); 14831fd3346740dfb7f47be9922312b68a4227fada96buzbee } 14841fd3346740dfb7f47be9922312b68a4227fada96buzbee } 14851500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru 14861fd3346740dfb7f47be9922312b68a4227fada96buzbee switch (dalvik_format) { 14878512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler case Instruction::k11n: // Add one immediate from vB. 14881fd3346740dfb7f47be9922312b68a4227fada96buzbee case Instruction::k21s: 14891fd3346740dfb7f47be9922312b68a4227fada96buzbee case Instruction::k31i: 14901fd3346740dfb7f47be9922312b68a4227fada96buzbee case Instruction::k21h: 14911500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(StringPrintf(", #0x%x", insn.vB)); 14921fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 14938512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler case Instruction::k51l: // Add one wide immediate. 149423b03b5b5fdaa517eda3b8b358752672cf6046b1Ian Rogers str.append(StringPrintf(", #%" PRId64, insn.vB_wide)); 14951fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 14968512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler case Instruction::k21c: // One register, one string/type/method index. 14971fd3346740dfb7f47be9922312b68a4227fada96buzbee case Instruction::k31c: 14981500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(StringPrintf(", index #0x%x", insn.vB)); 14991fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 15008512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler case Instruction::k22c: // Two registers, one string/type/method index. 15011500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(StringPrintf(", index #0x%x", insn.vC)); 15021fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 15038512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler case Instruction::k22s: // Add one immediate from vC. 15041fd3346740dfb7f47be9922312b68a4227fada96buzbee case Instruction::k22b: 15051500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(StringPrintf(", #0x%x", insn.vC)); 15061fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 15071500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru default: 15088512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Nothing left to print. 15091500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 151002c8cc6d1312a2b55533f02f6369dc7c94672f90Brian Carlstrom } 15111500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru 15120f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov if ((flags & Instruction::kBranch) != 0) { 15130f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov // For branches, decode the instructions to print out the branch targets. 15140f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov int offset = 0; 15150f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov switch (dalvik_format) { 15160f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov case Instruction::k21t: 15170f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov offset = insn.vB; 15180f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov break; 15190f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov case Instruction::k22t: 15200f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov offset = insn.vC; 15210f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov break; 15220f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov case Instruction::k10t: 15230f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov case Instruction::k20t: 15240f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov case Instruction::k30t: 15250f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov offset = insn.vA; 15260f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov break; 15270f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov default: 15280f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov LOG(FATAL) << "Unexpected branch format " << dalvik_format << " from " << insn.opcode; 15291500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 15300f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov } 15311500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(StringPrintf(", 0x%x (%c%x)", mir->offset + offset, 15320f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov offset > 0 ? '+' : '-', offset > 0 ? offset : -offset)); 15330f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov } 15341500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru 15351500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (nop) { 15361500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append("]--optimized away"); 15371500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 15381fd3346740dfb7f47be9922312b68a4227fada96buzbee } 15391fd3346740dfb7f47be9922312b68a4227fada96buzbee int length = str.length() + 1; 154083cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko ret = static_cast<char*>(arena_->Alloc(length, kArenaAllocDFInfo)); 15411fd3346740dfb7f47be9922312b68a4227fada96buzbee strncpy(ret, str.c_str(), length); 15421fd3346740dfb7f47be9922312b68a4227fada96buzbee return ret; 15431fd3346740dfb7f47be9922312b68a4227fada96buzbee} 15441fd3346740dfb7f47be9922312b68a4227fada96buzbee 15451fd3346740dfb7f47be9922312b68a4227fada96buzbee/* Turn method name into a legal Linux file name */ 15462ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MIRGraph::ReplaceSpecialChars(std::string& str) { 15479b7085a4e7c40e7fa01932ea1647a4a33ac1c585Brian Carlstrom static const struct { const char before; const char after; } match[] = { 15489b7085a4e7c40e7fa01932ea1647a4a33ac1c585Brian Carlstrom {'/', '-'}, {';', '#'}, {' ', '#'}, {'$', '+'}, 15499b7085a4e7c40e7fa01932ea1647a4a33ac1c585Brian Carlstrom {'(', '@'}, {')', '@'}, {'<', '='}, {'>', '='} 15509b7085a4e7c40e7fa01932ea1647a4a33ac1c585Brian Carlstrom }; 15511fd3346740dfb7f47be9922312b68a4227fada96buzbee for (unsigned int i = 0; i < sizeof(match)/sizeof(match[0]); i++) { 15521fd3346740dfb7f47be9922312b68a4227fada96buzbee std::replace(str.begin(), str.end(), match[i].before, match[i].after); 15531fd3346740dfb7f47be9922312b68a4227fada96buzbee } 15541fd3346740dfb7f47be9922312b68a4227fada96buzbee} 15551fd3346740dfb7f47be9922312b68a4227fada96buzbee 15562ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromstd::string MIRGraph::GetSSAName(int ssa_reg) { 155739ebcb800aabedd0ffa6aa4aeac8aa4194c66e61Ian Rogers // TODO: This value is needed for LLVM and debugging. Currently, we compute this and then copy to 155839ebcb800aabedd0ffa6aa4aeac8aa4194c66e61Ian Rogers // the arena. We should be smarter and just place straight into the arena, or compute the 155939ebcb800aabedd0ffa6aa4aeac8aa4194c66e61Ian Rogers // value more lazily. 15601500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru int vreg = SRegToVReg(ssa_reg); 15611500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (vreg >= static_cast<int>(GetFirstTempVR())) { 15621500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru return StringPrintf("t%d_%d", SRegToVReg(ssa_reg), GetSSASubscript(ssa_reg)); 15631500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } else { 15641500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru return StringPrintf("v%d_%d", SRegToVReg(ssa_reg), GetSSASubscript(ssa_reg)); 15651500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 15661fd3346740dfb7f47be9922312b68a4227fada96buzbee} 15671fd3346740dfb7f47be9922312b68a4227fada96buzbee 15681fd3346740dfb7f47be9922312b68a4227fada96buzbee// Similar to GetSSAName, but if ssa name represents an immediate show that as well. 15692ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromstd::string MIRGraph::GetSSANameWithConst(int ssa_reg, bool singles_only) { 15701fd3346740dfb7f47be9922312b68a4227fada96buzbee if (reg_location_ == NULL) { 15718512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Pre-SSA - just use the standard name. 15721fd3346740dfb7f47be9922312b68a4227fada96buzbee return GetSSAName(ssa_reg); 15731fd3346740dfb7f47be9922312b68a4227fada96buzbee } 15741fd3346740dfb7f47be9922312b68a4227fada96buzbee if (IsConst(reg_location_[ssa_reg])) { 15759944b3b792103cb72df1953b5502ced9bf128305Mark Mendell if (!singles_only && reg_location_[ssa_reg].wide && 15769944b3b792103cb72df1953b5502ced9bf128305Mark Mendell !reg_location_[ssa_reg].high_word) { 157723b03b5b5fdaa517eda3b8b358752672cf6046b1Ian Rogers return StringPrintf("v%d_%d#0x%" PRIx64, SRegToVReg(ssa_reg), GetSSASubscript(ssa_reg), 15781fd3346740dfb7f47be9922312b68a4227fada96buzbee ConstantValueWide(reg_location_[ssa_reg])); 15791fd3346740dfb7f47be9922312b68a4227fada96buzbee } else { 1580b1eba213afaf7fa6445de863ddc9680ab99762eaBrian Carlstrom return StringPrintf("v%d_%d#0x%x", SRegToVReg(ssa_reg), GetSSASubscript(ssa_reg), 15811fd3346740dfb7f47be9922312b68a4227fada96buzbee ConstantValue(reg_location_[ssa_reg])); 15821fd3346740dfb7f47be9922312b68a4227fada96buzbee } 15831fd3346740dfb7f47be9922312b68a4227fada96buzbee } else { 15841500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru int vreg = SRegToVReg(ssa_reg); 15851500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (vreg >= static_cast<int>(GetFirstTempVR())) { 15861500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru return StringPrintf("t%d_%d", SRegToVReg(ssa_reg), GetSSASubscript(ssa_reg)); 15871500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } else { 15881500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru return StringPrintf("v%d_%d", SRegToVReg(ssa_reg), GetSSASubscript(ssa_reg)); 15891500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 15901fd3346740dfb7f47be9922312b68a4227fada96buzbee } 15911fd3346740dfb7f47be9922312b68a4227fada96buzbee} 15921fd3346740dfb7f47be9922312b68a4227fada96buzbee 15932ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MIRGraph::GetBlockName(BasicBlock* bb, char* name) { 15941fd3346740dfb7f47be9922312b68a4227fada96buzbee switch (bb->block_type) { 15951fd3346740dfb7f47be9922312b68a4227fada96buzbee case kEntryBlock: 15961fd3346740dfb7f47be9922312b68a4227fada96buzbee snprintf(name, BLOCK_NAME_LEN, "entry_%d", bb->id); 15971fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 15981fd3346740dfb7f47be9922312b68a4227fada96buzbee case kExitBlock: 15991fd3346740dfb7f47be9922312b68a4227fada96buzbee snprintf(name, BLOCK_NAME_LEN, "exit_%d", bb->id); 16001fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 16011fd3346740dfb7f47be9922312b68a4227fada96buzbee case kDalvikByteCode: 16021fd3346740dfb7f47be9922312b68a4227fada96buzbee snprintf(name, BLOCK_NAME_LEN, "block%04x_%d", bb->start_offset, bb->id); 16031fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 16041fd3346740dfb7f47be9922312b68a4227fada96buzbee case kExceptionHandling: 16051fd3346740dfb7f47be9922312b68a4227fada96buzbee snprintf(name, BLOCK_NAME_LEN, "exception%04x_%d", bb->start_offset, 16061fd3346740dfb7f47be9922312b68a4227fada96buzbee bb->id); 16071fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 16081fd3346740dfb7f47be9922312b68a4227fada96buzbee default: 16091fd3346740dfb7f47be9922312b68a4227fada96buzbee snprintf(name, BLOCK_NAME_LEN, "_%d", bb->id); 16101fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 16111fd3346740dfb7f47be9922312b68a4227fada96buzbee } 16121fd3346740dfb7f47be9922312b68a4227fada96buzbee} 16131fd3346740dfb7f47be9922312b68a4227fada96buzbee 16142ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromconst char* MIRGraph::GetShortyFromTargetIdx(int target_idx) { 16150d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // TODO: for inlining support, use current code unit. 16161fd3346740dfb7f47be9922312b68a4227fada96buzbee const DexFile::MethodId& method_id = cu_->dex_file->GetMethodId(target_idx); 16171fd3346740dfb7f47be9922312b68a4227fada96buzbee return cu_->dex_file->GetShorty(method_id.proto_idx_); 16181fd3346740dfb7f47be9922312b68a4227fada96buzbee} 16191fd3346740dfb7f47be9922312b68a4227fada96buzbee 1620717a3e447c6f7a922cf9c3efe522747a187a045dSerguei Katkovconst char* MIRGraph::GetShortyFromMethodReference(const MethodReference& target_method) { 1621717a3e447c6f7a922cf9c3efe522747a187a045dSerguei Katkov const DexFile::MethodId& method_id = 1622717a3e447c6f7a922cf9c3efe522747a187a045dSerguei Katkov target_method.dex_file->GetMethodId(target_method.dex_method_index); 1623717a3e447c6f7a922cf9c3efe522747a187a045dSerguei Katkov return target_method.dex_file->GetShorty(method_id.proto_idx_); 1624717a3e447c6f7a922cf9c3efe522747a187a045dSerguei Katkov} 1625717a3e447c6f7a922cf9c3efe522747a187a045dSerguei Katkov 16261fd3346740dfb7f47be9922312b68a4227fada96buzbee/* Debug Utility - dump a compilation unit */ 16272ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MIRGraph::DumpMIRGraph() { 16281fd3346740dfb7f47be9922312b68a4227fada96buzbee const char* block_type_names[] = { 162917189ac098b2f156713db1821b49db7b2f018bbebuzbee "Null Block", 16301fd3346740dfb7f47be9922312b68a4227fada96buzbee "Entry Block", 16311fd3346740dfb7f47be9922312b68a4227fada96buzbee "Code Block", 16321fd3346740dfb7f47be9922312b68a4227fada96buzbee "Exit Block", 16331fd3346740dfb7f47be9922312b68a4227fada96buzbee "Exception Handling", 16341fd3346740dfb7f47be9922312b68a4227fada96buzbee "Catch Block" 16351fd3346740dfb7f47be9922312b68a4227fada96buzbee }; 16361fd3346740dfb7f47be9922312b68a4227fada96buzbee 16371fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "Compiling " << PrettyMethod(cu_->method_idx, *cu_->dex_file); 16388d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru LOG(INFO) << GetInsns(0) << " insns"; 16391fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << GetNumBlocks() << " blocks in total"; 16401fd3346740dfb7f47be9922312b68a4227fada96buzbee 1641e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (BasicBlock* bb : block_list_) { 16421fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << StringPrintf("Block %d (%s) (insn %04x - %04x%s)", 16431fd3346740dfb7f47be9922312b68a4227fada96buzbee bb->id, 16441fd3346740dfb7f47be9922312b68a4227fada96buzbee block_type_names[bb->block_type], 16451fd3346740dfb7f47be9922312b68a4227fada96buzbee bb->start_offset, 16461fd3346740dfb7f47be9922312b68a4227fada96buzbee bb->last_mir_insn ? bb->last_mir_insn->offset : bb->start_offset, 16471fd3346740dfb7f47be9922312b68a4227fada96buzbee bb->last_mir_insn ? "" : " empty"); 16480d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (bb->taken != NullBasicBlockId) { 16490d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee LOG(INFO) << " Taken branch: block " << bb->taken 16500d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee << "(0x" << std::hex << GetBasicBlock(bb->taken)->start_offset << ")"; 16511fd3346740dfb7f47be9922312b68a4227fada96buzbee } 16520d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (bb->fall_through != NullBasicBlockId) { 16530d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee LOG(INFO) << " Fallthrough : block " << bb->fall_through 16540d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee << " (0x" << std::hex << GetBasicBlock(bb->fall_through)->start_offset << ")"; 16551fd3346740dfb7f47be9922312b68a4227fada96buzbee } 16561fd3346740dfb7f47be9922312b68a4227fada96buzbee } 16571fd3346740dfb7f47be9922312b68a4227fada96buzbee} 16581fd3346740dfb7f47be9922312b68a4227fada96buzbee 16591fd3346740dfb7f47be9922312b68a4227fada96buzbee/* 16601fd3346740dfb7f47be9922312b68a4227fada96buzbee * Build an array of location records for the incoming arguments. 16611fd3346740dfb7f47be9922312b68a4227fada96buzbee * Note: one location record per word of arguments, with dummy 16621fd3346740dfb7f47be9922312b68a4227fada96buzbee * high-word loc for wide arguments. Also pull up any following 16631fd3346740dfb7f47be9922312b68a4227fada96buzbee * MOVE_RESULT and incorporate it into the invoke. 16641fd3346740dfb7f47be9922312b68a4227fada96buzbee */ 16651fd3346740dfb7f47be9922312b68a4227fada96buzbeeCallInfo* MIRGraph::NewMemCallInfo(BasicBlock* bb, MIR* mir, InvokeType type, 16662ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom bool is_range) { 1667f6c4b3ba3825de1dbb3e747a68b809c6cc8eb4dbMathieu Chartier CallInfo* info = static_cast<CallInfo*>(arena_->Alloc(sizeof(CallInfo), 166883cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko kArenaAllocMisc)); 16691fd3346740dfb7f47be9922312b68a4227fada96buzbee MIR* move_result_mir = FindMoveResult(bb, mir); 16701fd3346740dfb7f47be9922312b68a4227fada96buzbee if (move_result_mir == NULL) { 16711fd3346740dfb7f47be9922312b68a4227fada96buzbee info->result.location = kLocInvalid; 16721fd3346740dfb7f47be9922312b68a4227fada96buzbee } else { 16731fd3346740dfb7f47be9922312b68a4227fada96buzbee info->result = GetRawDest(move_result_mir); 16741fd3346740dfb7f47be9922312b68a4227fada96buzbee move_result_mir->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop); 16751fd3346740dfb7f47be9922312b68a4227fada96buzbee } 16761fd3346740dfb7f47be9922312b68a4227fada96buzbee info->num_arg_words = mir->ssa_rep->num_uses; 16771fd3346740dfb7f47be9922312b68a4227fada96buzbee info->args = (info->num_arg_words == 0) ? NULL : static_cast<RegLocation*> 167883cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko (arena_->Alloc(sizeof(RegLocation) * info->num_arg_words, kArenaAllocMisc)); 16791fd3346740dfb7f47be9922312b68a4227fada96buzbee for (int i = 0; i < info->num_arg_words; i++) { 16801fd3346740dfb7f47be9922312b68a4227fada96buzbee info->args[i] = GetRawSrc(mir, i); 16811fd3346740dfb7f47be9922312b68a4227fada96buzbee } 16821fd3346740dfb7f47be9922312b68a4227fada96buzbee info->opt_flags = mir->optimization_flags; 16831fd3346740dfb7f47be9922312b68a4227fada96buzbee info->type = type; 16841fd3346740dfb7f47be9922312b68a4227fada96buzbee info->is_range = is_range; 16851fd3346740dfb7f47be9922312b68a4227fada96buzbee info->index = mir->dalvikInsn.vB; 16861fd3346740dfb7f47be9922312b68a4227fada96buzbee info->offset = mir->offset; 1687f096aad9203d7c50b2f9cbe1c1215a50c265a059Vladimir Marko info->mir = mir; 16881fd3346740dfb7f47be9922312b68a4227fada96buzbee return info; 16891fd3346740dfb7f47be9922312b68a4227fada96buzbee} 16901fd3346740dfb7f47be9922312b68a4227fada96buzbee 16913aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler// Allocate a new MIR. 16923aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe BeylerMIR* MIRGraph::NewMIR() { 16933aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler MIR* mir = new (arena_) MIR(); 16943aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler return mir; 16953aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler} 16963aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 1697862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee// Allocate a new basic block. 16982ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromBasicBlock* MIRGraph::NewMemBB(BBType block_type, int block_id) { 1699e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* bb = new (arena_) BasicBlock(block_id, block_type, arena_); 17008512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 1701862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee // TUNING: better estimate of the exit block predecessors? 1702e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bb->predecessors.reserve((block_type == kExitBlock) ? 2048 : 2); 1703862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee block_id_map_.Put(block_id, block_id); 1704862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee return bb; 1705862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee} 17061fd3346740dfb7f47be9922312b68a4227fada96buzbee 17074e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beylervoid MIRGraph::InitializeConstantPropagation() { 17084e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beyler is_constant_v_ = new (arena_) ArenaBitVector(arena_, GetNumSSARegs(), false); 170983cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko constant_values_ = static_cast<int*>(arena_->Alloc(sizeof(int) * GetNumSSARegs(), kArenaAllocDFInfo)); 17104e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beyler} 17114e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beyler 17124e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beylervoid MIRGraph::InitializeMethodUses() { 17138512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // The gate starts by initializing the use counts. 17144e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beyler int num_ssa_regs = GetNumSSARegs(); 1715e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko use_counts_.clear(); 1716e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko use_counts_.reserve(num_ssa_regs + 32); 1717e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko use_counts_.resize(num_ssa_regs, 0u); 1718e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko raw_use_counts_.clear(); 1719e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko raw_use_counts_.reserve(num_ssa_regs + 32); 1720e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko raw_use_counts_.resize(num_ssa_regs, 0u); 17214e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beyler} 17224e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beyler 1723a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Markovoid MIRGraph::SSATransformationStart() { 1724a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko DCHECK(temp_scoped_alloc_.get() == nullptr); 1725a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko temp_scoped_alloc_.reset(ScopedArenaAllocator::Create(&cu_->arena_stack)); 1726f585e549682a98eec12f92033e9634dc162b7df8Vladimir Marko temp_.ssa.num_vregs = GetNumOfCodeAndTempVRs(); 1727f585e549682a98eec12f92033e9634dc162b7df8Vladimir Marko temp_.ssa.work_live_vregs = new (temp_scoped_alloc_.get()) ArenaBitVector( 1728f585e549682a98eec12f92033e9634dc162b7df8Vladimir Marko temp_scoped_alloc_.get(), temp_.ssa.num_vregs, false, kBitMapRegisterV); 17294e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beyler} 17304e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beyler 1731a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Markovoid MIRGraph::SSATransformationEnd() { 1732a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko // Verify the dataflow information after the pass. 1733a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko if (cu_->enable_debug & (1 << kDebugVerifyDataflow)) { 1734a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko VerifyDataflow(); 1735a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko } 1736a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko 1737f585e549682a98eec12f92033e9634dc162b7df8Vladimir Marko temp_.ssa.num_vregs = 0u; 1738f585e549682a98eec12f92033e9634dc162b7df8Vladimir Marko temp_.ssa.work_live_vregs = nullptr; 1739f585e549682a98eec12f92033e9634dc162b7df8Vladimir Marko temp_.ssa.def_block_matrix = nullptr; 1740a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko DCHECK(temp_scoped_alloc_.get() != nullptr); 1741a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko temp_scoped_alloc_.reset(); 1742c029c98cc056bc247b69160f413ee7ce9a93d8c3Johnny Qiu 1743c029c98cc056bc247b69160f413ee7ce9a93d8c3Johnny Qiu // Update the maximum number of reachable blocks. 1744c029c98cc056bc247b69160f413ee7ce9a93d8c3Johnny Qiu max_num_reachable_blocks_ = num_reachable_blocks_; 1745ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko 1746ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko // Mark MIR SSA representations as up to date. 1747ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko mir_ssa_rep_up_to_date_ = true; 1748a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko} 1749a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko 1750750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusorusize_t MIRGraph::GetNumDalvikInsns() const { 1751750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru size_t cumulative_size = 0u; 1752750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru bool counted_current_item = false; 1753750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru const uint8_t size_for_null_code_item = 2u; 1754750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru 1755750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru for (auto it : m_units_) { 1756750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru const DexFile::CodeItem* code_item = it->GetCodeItem(); 1757750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru // Even if the code item is null, we still count non-zero value so that 1758750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru // each m_unit is counted as having impact. 1759750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru cumulative_size += (code_item == nullptr ? 1760750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru size_for_null_code_item : code_item->insns_size_in_code_units_); 1761750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru if (code_item == current_code_item_) { 1762750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru counted_current_item = true; 1763750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru } 1764750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru } 1765750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru 1766750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru // If the current code item was not counted yet, count it now. 1767750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru // This can happen for example in unit tests where some fields like m_units_ 1768750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru // are not initialized. 1769750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru if (counted_current_item == false) { 1770750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru cumulative_size += (current_code_item_ == nullptr ? 1771750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru size_for_null_code_item : current_code_item_->insns_size_in_code_units_); 1772750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru } 1773750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru 1774750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru return cumulative_size; 1775750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru} 1776750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru 177755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Markostatic BasicBlock* SelectTopologicalSortOrderFallBack( 177855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko MIRGraph* mir_graph, const ArenaBitVector* current_loop, 177955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko const ScopedArenaVector<size_t>* visited_cnt_values, ScopedArenaAllocator* allocator, 178055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ScopedArenaVector<BasicBlockId>* tmp_stack) { 178155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // No true loop head has been found but there may be true loop heads after the mess we need 178255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // to resolve. To avoid taking one of those, pick the candidate with the highest number of 178355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // reachable unvisited nodes. That candidate will surely be a part of a loop. 178455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko BasicBlock* fall_back = nullptr; 178555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko size_t fall_back_num_reachable = 0u; 178655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Reuse the same bit vector for each candidate to mark reachable unvisited blocks. 178755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ArenaBitVector candidate_reachable(allocator, mir_graph->GetNumBlocks(), false, kBitMapMisc); 178855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko AllNodesIterator iter(mir_graph); 178955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko for (BasicBlock* candidate = iter.Next(); candidate != nullptr; candidate = iter.Next()) { 179055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (candidate->hidden || // Hidden, or 179155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko candidate->visited || // already processed, or 179255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko (*visited_cnt_values)[candidate->id] == 0u || // no processed predecessors, or 179355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko (current_loop != nullptr && // outside current loop. 179455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko !current_loop->IsBitSet(candidate->id))) { 179555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko continue; 179655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 179755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko DCHECK(tmp_stack->empty()); 179855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko tmp_stack->push_back(candidate->id); 179955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko candidate_reachable.ClearAllBits(); 180055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko size_t num_reachable = 0u; 180155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko while (!tmp_stack->empty()) { 180255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko BasicBlockId current_id = tmp_stack->back(); 180355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko tmp_stack->pop_back(); 180455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko BasicBlock* current_bb = mir_graph->GetBasicBlock(current_id); 180555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko DCHECK(current_bb != nullptr); 180655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ChildBlockIterator child_iter(current_bb, mir_graph); 180755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko BasicBlock* child_bb = child_iter.Next(); 180855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko for ( ; child_bb != nullptr; child_bb = child_iter.Next()) { 180955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko DCHECK(!child_bb->hidden); 181055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (child_bb->visited || // Already processed, or 181155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko (current_loop != nullptr && // outside current loop. 181255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko !current_loop->IsBitSet(child_bb->id))) { 181355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko continue; 181455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 181555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (!candidate_reachable.IsBitSet(child_bb->id)) { 181655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko candidate_reachable.SetBit(child_bb->id); 181755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko tmp_stack->push_back(child_bb->id); 181855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko num_reachable += 1u; 181955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 182055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 182155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 182255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (fall_back_num_reachable < num_reachable) { 182355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko fall_back_num_reachable = num_reachable; 182455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko fall_back = candidate; 182555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 182655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 182755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko return fall_back; 182855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko} 182944e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 183055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko// Compute from which unvisited blocks is bb_id reachable through unvisited blocks. 183155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Markostatic void ComputeUnvisitedReachableFrom(MIRGraph* mir_graph, BasicBlockId bb_id, 183255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ArenaBitVector* reachable, 183355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ScopedArenaVector<BasicBlockId>* tmp_stack) { 183455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // NOTE: Loop heads indicated by the "visited" flag. 183555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko DCHECK(tmp_stack->empty()); 183655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko reachable->ClearAllBits(); 183755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko tmp_stack->push_back(bb_id); 183855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko while (!tmp_stack->empty()) { 183955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko BasicBlockId current_id = tmp_stack->back(); 184055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko tmp_stack->pop_back(); 184155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko BasicBlock* current_bb = mir_graph->GetBasicBlock(current_id); 184255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko DCHECK(current_bb != nullptr); 1843e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (BasicBlockId pred_id : current_bb->predecessors) { 1844e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* pred_bb = mir_graph->GetBasicBlock(pred_id); 1845e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko DCHECK(pred_bb != nullptr); 184655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (!pred_bb->visited && !reachable->IsBitSet(pred_bb->id)) { 184755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko reachable->SetBit(pred_bb->id); 184855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko tmp_stack->push_back(pred_bb->id); 184955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 185055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 185144e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler } 185255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko} 185344e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 185455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Markovoid MIRGraph::ComputeTopologicalSortOrder() { 1855622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko ScopedArenaAllocator allocator(&cu_->arena_stack); 185655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko unsigned int num_blocks = GetNumBlocks(); 185755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko 1858622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko ScopedArenaQueue<BasicBlock*> q(allocator.Adapter()); 185955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ScopedArenaVector<size_t> visited_cnt_values(num_blocks, 0u, allocator.Adapter()); 186055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ScopedArenaVector<BasicBlockId> loop_head_stack(allocator.Adapter()); 186155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko size_t max_nested_loops = 0u; 186255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ArenaBitVector loop_exit_blocks(&allocator, num_blocks, false, kBitMapMisc); 186355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_exit_blocks.ClearAllBits(); 1864622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko 186555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Count the number of blocks to process and add the entry block(s). 186655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko unsigned int num_blocks_to_process = 0u; 1867e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (BasicBlock* bb : block_list_) { 186844e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler if (bb->hidden == true) { 186944e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler continue; 187044e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler } 187144e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 187255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko num_blocks_to_process += 1u; 1873622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko 1874e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko if (bb->predecessors.size() == 0u) { 187555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Add entry block to the queue. 187644e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler q.push(bb); 187744e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler } 187844e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler } 187944e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 1880e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko // Clear the topological order arrays. 1881e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_.clear(); 1882e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_.reserve(num_blocks); 1883e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_loop_ends_.clear(); 1884e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_loop_ends_.resize(num_blocks, 0u); 1885e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_indexes_.clear(); 1886e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_indexes_.resize(num_blocks, static_cast<uint16_t>(-1)); 188755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko 188855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Mark all blocks as unvisited. 188955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ClearAllVisitedFlags(); 189055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko 189155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // For loop heads, keep track from which blocks they are reachable not going through other 189255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // loop heads. Other loop heads are excluded to detect the heads of nested loops. The children 189355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // in this set go into the loop body, the other children are jumping over the loop. 189455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ScopedArenaVector<ArenaBitVector*> loop_head_reachable_from(allocator.Adapter()); 189555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_head_reachable_from.resize(num_blocks, nullptr); 189655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Reuse the same temp stack whenever calculating a loop_head_reachable_from[loop_head_id]. 189755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ScopedArenaVector<BasicBlockId> tmp_stack(allocator.Adapter()); 189855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko 189955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko while (num_blocks_to_process != 0u) { 1900622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko BasicBlock* bb = nullptr; 1901622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko if (!q.empty()) { 190255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko num_blocks_to_process -= 1u; 1903622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko // Get top. 1904622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko bb = q.front(); 1905622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko q.pop(); 190655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (bb->visited) { 190755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Loop head: it was already processed, mark end and copy exit blocks to the queue. 190855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko DCHECK(q.empty()) << PrettyMethod(cu_->method_idx, *cu_->dex_file); 1909e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko uint16_t idx = static_cast<uint16_t>(topological_order_.size()); 1910e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_loop_ends_[topological_order_indexes_[bb->id]] = idx; 191155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko DCHECK_EQ(loop_head_stack.back(), bb->id); 191255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_head_stack.pop_back(); 191355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ArenaBitVector* reachable = 191455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_head_stack.empty() ? nullptr : loop_head_reachable_from[loop_head_stack.back()]; 191555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko for (BasicBlockId candidate_id : loop_exit_blocks.Indexes()) { 191655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (reachable == nullptr || reachable->IsBitSet(candidate_id)) { 191755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko q.push(GetBasicBlock(candidate_id)); 191855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // NOTE: The BitVectorSet::IndexIterator will not check the pointed-to bit again, 191955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // so clearing the bit has no effect on the iterator. 192055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_exit_blocks.ClearBit(candidate_id); 192155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 192255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 192355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko continue; 192455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 1925622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko } else { 192655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Find the new loop head. 192755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko AllNodesIterator iter(this); 192855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko while (true) { 192955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko BasicBlock* candidate = iter.Next(); 193055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (candidate == nullptr) { 193155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // We did not find a true loop head, fall back to a reachable block in any loop. 193255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ArenaBitVector* current_loop = 193355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_head_stack.empty() ? nullptr : loop_head_reachable_from[loop_head_stack.back()]; 193455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko bb = SelectTopologicalSortOrderFallBack(this, current_loop, &visited_cnt_values, 193555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko &allocator, &tmp_stack); 193655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko DCHECK(bb != nullptr) << PrettyMethod(cu_->method_idx, *cu_->dex_file); 193755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (kIsDebugBuild && cu_->dex_file != nullptr) { 193855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko LOG(INFO) << "Topological sort order: Using fall-back in " 193955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko << PrettyMethod(cu_->method_idx, *cu_->dex_file) << " BB #" << bb->id 194055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko << " @0x" << std::hex << bb->start_offset 194155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko << ", num_blocks = " << std::dec << num_blocks; 194255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 194355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko break; 194455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 194555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (candidate->hidden || // Hidden, or 194655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko candidate->visited || // already processed, or 194755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko visited_cnt_values[candidate->id] == 0u || // no processed predecessors, or 194855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko (!loop_head_stack.empty() && // outside current loop. 194955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko !loop_head_reachable_from[loop_head_stack.back()]->IsBitSet(candidate->id))) { 1950622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko continue; 1951622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko } 195255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko 1953e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (BasicBlockId pred_id : candidate->predecessors) { 1954e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* pred_bb = GetBasicBlock(pred_id); 1955e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko DCHECK(pred_bb != nullptr); 195655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (pred_bb != candidate && !pred_bb->visited && 195755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko !pred_bb->dominators->IsBitSet(candidate->id)) { 1958e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko candidate = nullptr; // Set candidate to null to indicate failure. 1959e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko break; 1960622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko } 1961622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko } 1962e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko if (candidate != nullptr) { 196355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko bb = candidate; 196455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko break; 196555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 1966622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko } 196755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Compute blocks from which the loop head is reachable and process those blocks first. 196855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ArenaBitVector* reachable = 196955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko new (&allocator) ArenaBitVector(&allocator, num_blocks, false, kBitMapMisc); 197055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_head_reachable_from[bb->id] = reachable; 197155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ComputeUnvisitedReachableFrom(this, bb->id, reachable, &tmp_stack); 197255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Now mark as loop head. (Even if it's only a fall back when we don't find a true loop.) 197355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_head_stack.push_back(bb->id); 197455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko max_nested_loops = std::max(max_nested_loops, loop_head_stack.size()); 1975622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko } 197644e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 197744e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler DCHECK_EQ(bb->hidden, false); 1978622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko DCHECK_EQ(bb->visited, false); 1979622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko bb->visited = true; 19808b858e16563ebf8e522df026a6ab409f1bd9b3deVladimir Marko bb->nesting_depth = loop_head_stack.size(); 198144e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 1982622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko // Now add the basic block. 1983e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko uint16_t idx = static_cast<uint16_t>(topological_order_.size()); 1984e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_indexes_[bb->id] = idx; 1985e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_.push_back(bb->id); 198644e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 198755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Update visited_cnt_values for children. 1988622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko ChildBlockIterator succIter(bb, this); 1989622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko BasicBlock* successor = succIter.Next(); 1990622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko for ( ; successor != nullptr; successor = succIter.Next()) { 199155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (successor->hidden) { 1992622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko continue; 1993622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko } 199444e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 199555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // One more predecessor was visited. 199655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko visited_cnt_values[successor->id] += 1u; 1997e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko if (visited_cnt_values[successor->id] == successor->predecessors.size()) { 199855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (loop_head_stack.empty() || 199955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_head_reachable_from[loop_head_stack.back()]->IsBitSet(successor->id)) { 200055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko q.push(successor); 200155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } else { 200255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko DCHECK(!loop_exit_blocks.IsBitSet(successor->id)); 200355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_exit_blocks.SetBit(successor->id); 200455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 200544e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler } 200644e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler } 200744e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler } 200855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko 200955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Prepare the loop head stack for iteration. 2010e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_loop_head_stack_.clear(); 2011e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_loop_head_stack_.reserve(max_nested_loops); 2012415ac88a6471792a28cf2b457fe4ba9dc099396eVladimir Marko max_nested_loops_ = max_nested_loops; 2013ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko topological_order_up_to_date_ = true; 201444e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler} 201544e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 201644e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beylerbool BasicBlock::IsExceptionBlock() const { 201744e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler if (block_type == kExceptionHandling) { 201844e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler return true; 201944e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler } 202044e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler return false; 202144e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler} 202244e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 2023f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe BeylerChildBlockIterator::ChildBlockIterator(BasicBlock* bb, MIRGraph* mir_graph) 2024f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler : basic_block_(bb), mir_graph_(mir_graph), visited_fallthrough_(false), 2025f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler visited_taken_(false), have_successors_(false) { 2026f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler // Check if we actually do have successors. 2027f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler if (basic_block_ != 0 && basic_block_->successor_block_list_type != kNotUsed) { 2028f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler have_successors_ = true; 2029e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko successor_iter_ = basic_block_->successor_blocks.cbegin(); 2030f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler } 2031f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler} 2032f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler 2033f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe BeylerBasicBlock* ChildBlockIterator::Next() { 2034f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler // We check if we have a basic block. If we don't we cannot get next child. 2035f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler if (basic_block_ == nullptr) { 2036f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler return nullptr; 2037f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler } 2038f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler 2039f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler // If we haven't visited fallthrough, return that. 2040f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler if (visited_fallthrough_ == false) { 2041f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler visited_fallthrough_ = true; 2042f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler 2043f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler BasicBlock* result = mir_graph_->GetBasicBlock(basic_block_->fall_through); 2044f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler if (result != nullptr) { 2045f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler return result; 2046f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler } 2047f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler } 2048f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler 2049f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler // If we haven't visited taken, return that. 2050f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler if (visited_taken_ == false) { 2051f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler visited_taken_ = true; 2052f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler 2053f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler BasicBlock* result = mir_graph_->GetBasicBlock(basic_block_->taken); 2054f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler if (result != nullptr) { 2055f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler return result; 2056f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler } 2057f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler } 2058f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler 2059f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler // We visited both taken and fallthrough. Now check if we have successors we need to visit. 2060f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler if (have_successors_ == true) { 2061f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler // Get information about next successor block. 2062e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko auto end = basic_block_->successor_blocks.cend(); 2063e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko while (successor_iter_ != end) { 2064e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko SuccessorBlockInfo* successor_block_info = *successor_iter_; 2065e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko ++successor_iter_; 2066989367a47b015dd85f850cf756b436fb044b5aeaNiranjan Kumar // If block was replaced by zero block, take next one. 2067989367a47b015dd85f850cf756b436fb044b5aeaNiranjan Kumar if (successor_block_info->block != NullBasicBlockId) { 2068989367a47b015dd85f850cf756b436fb044b5aeaNiranjan Kumar return mir_graph_->GetBasicBlock(successor_block_info->block); 2069989367a47b015dd85f850cf756b436fb044b5aeaNiranjan Kumar } 2070f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler } 2071f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler } 2072f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler 2073f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler // We do not have anything. 2074f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler return nullptr; 2075f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler} 2076f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler 20778512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe BeylerBasicBlock* BasicBlock::Copy(CompilationUnit* c_unit) { 20788512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler MIRGraph* mir_graph = c_unit->mir_graph.get(); 20798512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return Copy(mir_graph); 20808512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 20813aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 20828512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe BeylerBasicBlock* BasicBlock::Copy(MIRGraph* mir_graph) { 20838512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler BasicBlock* result_bb = mir_graph->CreateNewBB(block_type); 20843aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 20858512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // We don't do a memcpy style copy here because it would lead to a lot of things 20868512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // to clean up. Let us do it by hand instead. 20878512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Copy in taken and fallthrough. 20888512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler result_bb->fall_through = fall_through; 20898512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler result_bb->taken = taken; 20903aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 20918512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Copy successor links if needed. 20928512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler ArenaAllocator* arena = mir_graph->GetArena(); 20933aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 20948512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler result_bb->successor_block_list_type = successor_block_list_type; 20958512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (result_bb->successor_block_list_type != kNotUsed) { 2096e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko result_bb->successor_blocks.reserve(successor_blocks.size()); 2097e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (SuccessorBlockInfo* sbi_old : successor_blocks) { 2098e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko SuccessorBlockInfo* sbi_new = static_cast<SuccessorBlockInfo*>( 2099e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko arena->Alloc(sizeof(SuccessorBlockInfo), kArenaAllocSuccessor)); 21008512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler memcpy(sbi_new, sbi_old, sizeof(SuccessorBlockInfo)); 2101e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko result_bb->successor_blocks.push_back(sbi_new); 21023aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler } 21038512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 21043aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 21058512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Copy offset, method. 21068512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler result_bb->start_offset = start_offset; 21073aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 21088512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Now copy instructions. 21098512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler for (MIR* mir = first_mir_insn; mir != 0; mir = mir->next) { 21108512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Get a copy first. 21118512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler MIR* copy = mir->Copy(mir_graph); 21123aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 21138512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Append it. 21148512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler result_bb->AppendMIR(copy); 21153aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler } 21163aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 21178512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return result_bb; 21183aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler} 21193aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 21203aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe BeylerMIR* MIR::Copy(MIRGraph* mir_graph) { 21213aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler MIR* res = mir_graph->NewMIR(); 21223aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler *res = *this; 21233aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 21243aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler // Remove links 21253aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler res->next = nullptr; 21263aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler res->bb = NullBasicBlockId; 21273aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler res->ssa_rep = nullptr; 21283aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 21293aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler return res; 21303aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler} 21313aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 21323aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe BeylerMIR* MIR::Copy(CompilationUnit* c_unit) { 21333aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler return Copy(c_unit->mir_graph.get()); 21343aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler} 21353aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 21363aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyleruint32_t SSARepresentation::GetStartUseIndex(Instruction::Code opcode) { 21373aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler // Default result. 21383aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler int res = 0; 21393aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 21403aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler // We are basically setting the iputs to their igets counterparts. 21413aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler switch (opcode) { 21423aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT: 21433aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT_OBJECT: 21443aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT_BOOLEAN: 21453aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT_BYTE: 21463aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT_CHAR: 21473aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT_SHORT: 21483aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT_QUICK: 21493aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT_OBJECT_QUICK: 215037f05ef45e0393de812d51261dc293240c17294dFred Shih case Instruction::IPUT_BOOLEAN_QUICK: 215137f05ef45e0393de812d51261dc293240c17294dFred Shih case Instruction::IPUT_BYTE_QUICK: 215237f05ef45e0393de812d51261dc293240c17294dFred Shih case Instruction::IPUT_CHAR_QUICK: 215337f05ef45e0393de812d51261dc293240c17294dFred Shih case Instruction::IPUT_SHORT_QUICK: 21543aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::APUT: 21553aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::APUT_OBJECT: 21563aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::APUT_BOOLEAN: 21573aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::APUT_BYTE: 21583aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::APUT_CHAR: 21593aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::APUT_SHORT: 21603aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::SPUT: 21613aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::SPUT_OBJECT: 21623aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::SPUT_BOOLEAN: 21633aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::SPUT_BYTE: 21643aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::SPUT_CHAR: 21653aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::SPUT_SHORT: 21663aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler // Skip the VR containing what to store. 21673aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler res = 1; 21683aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler break; 21693aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT_WIDE: 21703aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT_WIDE_QUICK: 21713aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::APUT_WIDE: 21723aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::SPUT_WIDE: 21733aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler // Skip the two VRs containing what to store. 21743aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler res = 2; 21753aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler break; 21763aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler default: 21773aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler // Do nothing in the general case. 21783aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler break; 21793aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler } 21803aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 21813aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler return res; 21823aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler} 21833aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 2184c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler/** 2185c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler * @brief Given a decoded instruction, it checks whether the instruction 2186c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler * sets a constant and if it does, more information is provided about the 2187c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler * constant being set. 2188c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler * @param ptr_value pointer to a 64-bit holder for the constant. 2189c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler * @param wide Updated by function whether a wide constant is being set by bytecode. 2190c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler * @return Returns false if the decoded instruction does not represent a constant bytecode. 2191c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler */ 2192c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beylerbool MIR::DecodedInstruction::GetConstant(int64_t* ptr_value, bool* wide) const { 2193c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler bool sets_const = true; 2194c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler int64_t value = vB; 2195c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler 2196c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler DCHECK(ptr_value != nullptr); 2197c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler DCHECK(wide != nullptr); 2198c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler 2199c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler switch (opcode) { 2200c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler case Instruction::CONST_4: 2201c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler case Instruction::CONST_16: 2202c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler case Instruction::CONST: 2203c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler *wide = false; 2204c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler value <<= 32; // In order to get the sign extend. 2205c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler value >>= 32; 2206c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler break; 2207c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler case Instruction::CONST_HIGH16: 2208c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler *wide = false; 2209c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler value <<= 48; // In order to get the sign extend. 2210c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler value >>= 32; 2211c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler break; 2212c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler case Instruction::CONST_WIDE_16: 2213c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler case Instruction::CONST_WIDE_32: 2214c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler *wide = true; 2215c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler value <<= 32; // In order to get the sign extend. 2216c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler value >>= 32; 2217c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler break; 2218c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler case Instruction::CONST_WIDE: 2219c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler *wide = true; 2220c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler value = vB_wide; 2221c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler break; 2222c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler case Instruction::CONST_WIDE_HIGH16: 2223c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler *wide = true; 2224c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler value <<= 48; // In order to get the sign extend. 2225c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler break; 2226c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler default: 2227c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler sets_const = false; 2228c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler break; 2229c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler } 2230c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler 2231c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler if (sets_const) { 2232c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler *ptr_value = value; 2233c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler } 2234c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler 2235c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler return sets_const; 2236c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler} 22378512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 22388512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylervoid BasicBlock::ResetOptimizationFlags(uint16_t reset_flags) { 22398512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Reset flags for all MIRs in bb. 22408512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler for (MIR* mir = first_mir_insn; mir != NULL; mir = mir->next) { 22418512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler mir->optimization_flags &= (~reset_flags); 22428512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 22438512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 22448512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 2245cb873d8fd06b7dde4b69c5987b4eaf541d345a50Vladimir Markovoid BasicBlock::Kill(MIRGraph* mir_graph) { 2246e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (BasicBlockId pred_id : predecessors) { 2247e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* pred_bb = mir_graph->GetBasicBlock(pred_id); 2248e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko DCHECK(pred_bb != nullptr); 22498512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 22508512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Sadly we have to go through the children by hand here. 22518512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler pred_bb->ReplaceChild(id, NullBasicBlockId); 22528512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 2253cb873d8fd06b7dde4b69c5987b4eaf541d345a50Vladimir Marko predecessors.clear(); 22548512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 2255312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko // Mark as dead and hidden. 2256312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko block_type = kDead; 2257312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko hidden = true; 2258312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko 2259312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko // Detach it from its MIRs so we don't generate code for them. Also detached MIRs 2260312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko // are updated to know that they no longer have a parent. 2261312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko for (MIR* mir = first_mir_insn; mir != nullptr; mir = mir->next) { 2262312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko mir->bb = NullBasicBlockId; 2263312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko } 2264312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko first_mir_insn = nullptr; 2265312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko last_mir_insn = nullptr; 2266312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko 2267312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko data_flow_info = nullptr; 2268312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko 2269312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko // Erase this bb from all children's predecessors and kill unreachable children. 2270312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko ChildBlockIterator iter(this, mir_graph); 2271312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko for (BasicBlock* succ_bb = iter.Next(); succ_bb != nullptr; succ_bb = iter.Next()) { 2272312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko succ_bb->ErasePredecessor(id); 2273312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko } 2274312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko 2275312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko // Remove links to children. 2276312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko fall_through = NullBasicBlockId; 2277312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko taken = NullBasicBlockId; 2278312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko successor_block_list_type = kNotUsed; 2279312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko 2280312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko if (kIsDebugBuild) { 2281312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko if (catch_entry) { 2282312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko DCHECK_EQ(mir_graph->catches_.count(start_offset), 1u); 2283312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko mir_graph->catches_.erase(start_offset); 2284312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko } 2285312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko } 2286312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko} 2287312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko 22888512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylerbool BasicBlock::IsSSALiveOut(const CompilationUnit* c_unit, int ssa_reg) { 22898512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // In order to determine if the ssa reg is live out, we scan all the MIRs. We remember 22908512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // the last SSA number of the same dalvik register. At the end, if it is different than ssa_reg, 22918512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // then it is not live out of this BB. 22928512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler int dalvik_reg = c_unit->mir_graph->SRegToVReg(ssa_reg); 22938512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 22948512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler int last_ssa_reg = -1; 22958512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 22968512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Walk through the MIRs backwards. 22978512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler for (MIR* mir = first_mir_insn; mir != nullptr; mir = mir->next) { 22988512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Get ssa rep. 22998512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler SSARepresentation *ssa_rep = mir->ssa_rep; 23008512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23018512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Go through the defines for this MIR. 23028512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler for (int i = 0; i < ssa_rep->num_defs; i++) { 23038512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler DCHECK(ssa_rep->defs != nullptr); 23048512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23058512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Get the ssa reg. 23068512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler int def_ssa_reg = ssa_rep->defs[i]; 23078512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23088512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Get dalvik reg. 23098512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler int def_dalvik_reg = c_unit->mir_graph->SRegToVReg(def_ssa_reg); 23108512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23118512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Compare dalvik regs. 23128512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (dalvik_reg == def_dalvik_reg) { 23138512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // We found a def of the register that we are being asked about. 23148512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Remember it. 23158512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_ssa_reg = def_ssa_reg; 23168512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 23178512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 23188512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 23198512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23208512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (last_ssa_reg == -1) { 23218512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // If we get to this point we couldn't find a define of register user asked about. 23228512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Let's assume the user knows what he's doing so we can be safe and say that if we 23238512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // couldn't find a def, it is live out. 23248512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return true; 23258512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 23268512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23278512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // If it is not -1, we found a match, is it ssa_reg? 23288512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return (ssa_reg == last_ssa_reg); 23298512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 23308512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23318512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylerbool BasicBlock::ReplaceChild(BasicBlockId old_bb, BasicBlockId new_bb) { 23328512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // We need to check taken, fall_through, and successor_blocks to replace. 23338512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler bool found = false; 23348512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (taken == old_bb) { 23358512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler taken = new_bb; 23368512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler found = true; 23378512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 23388512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23398512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (fall_through == old_bb) { 23408512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler fall_through = new_bb; 23418512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler found = true; 23428512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 23438512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23448512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (successor_block_list_type != kNotUsed) { 2345e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (SuccessorBlockInfo* successor_block_info : successor_blocks) { 23468512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (successor_block_info->block == old_bb) { 23478512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler successor_block_info->block = new_bb; 23488512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler found = true; 23498512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 23508512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 23518512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 23528512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23538512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return found; 23548512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 23558512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 2356e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Markovoid BasicBlock::ErasePredecessor(BasicBlockId old_pred) { 2357e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko auto pos = std::find(predecessors.begin(), predecessors.end(), old_pred); 2358e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko DCHECK(pos != predecessors.end()); 2359312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko // It's faster to move the back() to *pos than erase(pos). 2360312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko *pos = predecessors.back(); 2361312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko predecessors.pop_back(); 2362312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko size_t idx = std::distance(predecessors.begin(), pos); 2363312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko for (MIR* mir = first_mir_insn; mir != nullptr; mir = mir->next) { 2364312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko if (static_cast<int>(mir->dalvikInsn.opcode) != kMirOpPhi) { 2365312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko break; 2366312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko } 2367312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko DCHECK_EQ(mir->ssa_rep->num_uses - 1u, predecessors.size()); 2368312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko DCHECK_EQ(mir->meta.phi_incoming[idx], old_pred); 2369312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko mir->meta.phi_incoming[idx] = mir->meta.phi_incoming[predecessors.size()]; 2370312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko mir->ssa_rep->uses[idx] = mir->ssa_rep->uses[predecessors.size()]; 2371312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko mir->ssa_rep->num_uses = predecessors.size(); 2372312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko } 2373e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko} 23748512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 2375e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Markovoid BasicBlock::UpdatePredecessor(BasicBlockId old_pred, BasicBlockId new_pred) { 2376e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko DCHECK_NE(new_pred, NullBasicBlockId); 2377e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko auto pos = std::find(predecessors.begin(), predecessors.end(), old_pred); 2378312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko DCHECK(pos != predecessors.end()); 2379312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko *pos = new_pred; 2380312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko size_t idx = std::distance(predecessors.begin(), pos); 2381312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko for (MIR* mir = first_mir_insn; mir != nullptr; mir = mir->next) { 2382312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko if (static_cast<int>(mir->dalvikInsn.opcode) != kMirOpPhi) { 2383312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko break; 2384312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko } 2385312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko DCHECK_EQ(mir->meta.phi_incoming[idx], old_pred); 2386312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko mir->meta.phi_incoming[idx] = new_pred; 23878512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 23888512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 23898512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23908512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler// Create a new basic block with block_id as num_blocks_ that is 23918512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler// post-incremented. 23928512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe BeylerBasicBlock* MIRGraph::CreateNewBB(BBType block_type) { 2393ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko BasicBlockId id = static_cast<BasicBlockId>(block_list_.size()); 2394ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko BasicBlock* res = NewMemBB(block_type, id); 2395e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko block_list_.push_back(res); 23968512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return res; 23978512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 23988512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23992469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beylervoid MIRGraph::CalculateBasicBlockInformation() { 24002469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler PassDriverMEPostOpt driver(cu_); 24012469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler driver.Launch(); 24022469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler} 24032469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler 2404fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beylerint MIR::DecodedInstruction::FlagsOf() const { 2405fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler // Calculate new index. 2406fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler int idx = static_cast<int>(opcode) - kNumPackedOpcodes; 2407fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler 2408fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler // Check if it is an extended or not. 2409fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler if (idx < 0) { 2410fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::FlagsOf(opcode); 2411fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler } 2412fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler 2413fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler // For extended, we use a switch. 2414fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler switch (static_cast<int>(opcode)) { 2415fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPhi: 2416fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2417fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpCopy: 2418fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2419fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpFusedCmplFloat: 2420fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue | Instruction::kBranch; 2421fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpFusedCmpgFloat: 2422fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue | Instruction::kBranch; 2423fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpFusedCmplDouble: 2424fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue | Instruction::kBranch; 2425fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpFusedCmpgDouble: 2426fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue | Instruction::kBranch; 2427fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpFusedCmpLong: 2428fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue | Instruction::kBranch; 2429fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpNop: 2430fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2431fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpNullCheck: 2432fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue | Instruction::kThrow; 2433fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpRangeCheck: 2434fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue | Instruction::kThrow; 2435fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpDivZeroCheck: 2436fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue | Instruction::kThrow; 2437fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpCheck: 2438b7fc629dc562ee9f3df04a112a70b7868664f94dUdayan Banerji return Instruction::kContinue | Instruction::kThrow; 2439fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpCheckPart2: 2440b7fc629dc562ee9f3df04a112a70b7868664f94dUdayan Banerji return Instruction::kContinue; 2441fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpSelect: 2442fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2443fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpConstVector: 2444fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2445fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpMoveVector: 2446fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2447fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedMultiply: 2448fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2449fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedAddition: 2450fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2451fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedSubtract: 2452fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2453fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedShiftLeft: 2454fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2455fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedSignedShiftRight: 2456fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2457fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedUnsignedShiftRight: 2458fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2459fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedAnd: 2460fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2461fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedOr: 2462fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2463fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedXor: 2464fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2465fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedAddReduce: 2466fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2467fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedReduce: 2468fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2469fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedSet: 2470fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2471fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpReserveVectorRegisters: 2472fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2473fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpReturnVectorRegisters: 2474fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2475b7fc629dc562ee9f3df04a112a70b7868664f94dUdayan Banerji case kMirOpMemBarrier: 2476b7fc629dc562ee9f3df04a112a70b7868664f94dUdayan Banerji return Instruction::kContinue; 2477b7fc629dc562ee9f3df04a112a70b7868664f94dUdayan Banerji case kMirOpPackedArrayGet: 2478b7fc629dc562ee9f3df04a112a70b7868664f94dUdayan Banerji return Instruction::kContinue | Instruction::kThrow; 2479b7fc629dc562ee9f3df04a112a70b7868664f94dUdayan Banerji case kMirOpPackedArrayPut: 2480b7fc629dc562ee9f3df04a112a70b7868664f94dUdayan Banerji return Instruction::kContinue | Instruction::kThrow; 2481a262f7707330dccfb50af6345813083182b61043Ningsheng Jian case kMirOpMaddInt: 2482a262f7707330dccfb50af6345813083182b61043Ningsheng Jian case kMirOpMsubInt: 2483a262f7707330dccfb50af6345813083182b61043Ningsheng Jian case kMirOpMaddLong: 2484a262f7707330dccfb50af6345813083182b61043Ningsheng Jian case kMirOpMsubLong: 2485a262f7707330dccfb50af6345813083182b61043Ningsheng Jian return Instruction::kContinue; 2486fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler default: 2487fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler LOG(WARNING) << "ExtendedFlagsOf: Unhandled case: " << static_cast<int> (opcode); 2488fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return 0; 2489fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler } 2490fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler} 24917934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom} // namespace art 2492