mir_graph.cc revision f41b92c7a2fcdd411b9edd7070e4729ea18e0ba6
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", 731fd3346740dfb7f47be9922312b68a4227fada96buzbee}; 741fd3346740dfb7f47be9922312b68a4227fada96buzbee 75862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbeeMIRGraph::MIRGraph(CompilationUnit* cu, ArenaAllocator* arena) 761fd3346740dfb7f47be9922312b68a4227fada96buzbee : reg_location_(NULL), 778081d2b8d7a743729557051d0294e040e61c747aVladimir Marko block_id_map_(std::less<unsigned int>(), arena->Adapter()), 781fd3346740dfb7f47be9922312b68a4227fada96buzbee cu_(cu), 79e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko ssa_base_vregs_(arena->Adapter(kArenaAllocSSAToDalvikMap)), 80e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko ssa_subscripts_(arena->Adapter(kArenaAllocSSAToDalvikMap)), 81311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee vreg_to_ssa_map_(NULL), 82311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee ssa_last_defs_(NULL), 83311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee is_constant_v_(NULL), 84311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee constant_values_(NULL), 85e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko use_counts_(arena->Adapter()), 86e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko raw_use_counts_(arena->Adapter()), 87311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee num_reachable_blocks_(0), 884896d7b6fb75add25f2d6ba84346ac83d8ba9d51Jean Christophe Beyler max_num_reachable_blocks_(0), 89312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko dfs_orders_up_to_date_(false), 90e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko dfs_order_(arena->Adapter(kArenaAllocDfsPreOrder)), 91e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko dfs_post_order_(arena->Adapter(kArenaAllocDfsPostOrder)), 92e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko dom_post_order_traversal_(arena->Adapter(kArenaAllocDomPostOrder)), 93e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_(arena->Adapter(kArenaAllocTopologicalSortOrder)), 94e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_loop_ends_(arena->Adapter(kArenaAllocTopologicalSortOrder)), 95e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_indexes_(arena->Adapter(kArenaAllocTopologicalSortOrder)), 96e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_loop_head_stack_(arena->Adapter(kArenaAllocTopologicalSortOrder)), 97415ac88a6471792a28cf2b457fe4ba9dc099396eVladimir Marko max_nested_loops_(0u), 98311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee i_dom_list_(NULL), 99bfea9c29e809e04bde4a46591fea64c5a7b922fbVladimir Marko temp_scoped_alloc_(), 100e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko block_list_(arena->Adapter(kArenaAllocBBList)), 101311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee try_block_addr_(NULL), 102311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee entry_block_(NULL), 103311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee exit_block_(NULL), 104311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee num_blocks_(0), 105311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee current_code_item_(NULL), 106e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko dex_pc_to_block_map_(arena->Adapter()), 1078081d2b8d7a743729557051d0294e040e61c747aVladimir Marko m_units_(arena->Adapter()), 1088081d2b8d7a743729557051d0294e040e61c747aVladimir Marko method_stack_(arena->Adapter()), 109311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee current_method_(kInvalidEntry), 110311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee current_offset_(kInvalidEntry), 111311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee def_count_(0), 112311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee opcode_count_(NULL), 1131fd3346740dfb7f47be9922312b68a4227fada96buzbee num_ssa_regs_(0), 1148081d2b8d7a743729557051d0294e040e61c747aVladimir Marko extended_basic_blocks_(arena->Adapter()), 1151fd3346740dfb7f47be9922312b68a4227fada96buzbee method_sreg_(0), 116862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee attributes_(METHOD_IS_LEAF), // Start with leaf assumption, change on encountering invoke. 117862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee checkstats_(NULL), 118b48819db07f9a0992a72173380c24249d7fc648abuzbee arena_(arena), 119b48819db07f9a0992a72173380c24249d7fc648abuzbee backward_branches_(0), 120da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru forward_branches_(0), 121da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru num_non_special_compiler_temps_(0), 1228d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru max_available_special_compiler_temps_(1), // We only need the method ptr as a special temp for now. 1238d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru requested_backend_temp_(false), 1248d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru compiler_temps_committed_(false), 125be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko punt_to_interpreter_(false), 1263d73ba2ce682edfaf41f29521bd6039c6499a1c5Vladimir Marko merged_df_flags_(0u), 127e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko ifield_lowering_infos_(arena->Adapter(kArenaAllocLoweringInfo)), 128e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko sfield_lowering_infos_(arena->Adapter(kArenaAllocLoweringInfo)), 129e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko method_lowering_infos_(arena->Adapter(kArenaAllocLoweringInfo)), 130e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko gen_suspend_test_list_(arena->Adapter()) { 131f585e549682a98eec12f92033e9634dc162b7df8Vladimir Marko memset(&temp_, 0, sizeof(temp_)); 132e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko use_counts_.reserve(256); 133e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko raw_use_counts_.reserve(256); 134e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko block_list_.reserve(100); 135862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee try_block_addr_ = new (arena_) ArenaBitVector(arena_, 0, true /* expandable */); 1368d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru 1378d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru 1388d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru if (cu_->instruction_set == kX86 || cu_->instruction_set == kX86_64) { 1398d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru // X86 requires a temp to keep track of the method address. 1408d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru // TODO For x86_64, addressing can be done with RIP. When that is implemented, 1418d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru // this needs to be updated to reserve 0 temps for BE. 1428d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru max_available_non_special_compiler_temps_ = cu_->target64 ? 2 : 1; 1438d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru reserved_temps_for_backend_ = max_available_non_special_compiler_temps_; 1448d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru } else { 1458d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru // Other architectures do not have a known lower bound for non-special temps. 1468d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru // We allow the update of the max to happen at BE initialization stage and simply set 0 for now. 1478d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru max_available_non_special_compiler_temps_ = 0; 1488d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru reserved_temps_for_backend_ = 0; 1498d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru } 150311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 151311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 1526282dc12440a2072dc06a616160027ff21bd895eIan RogersMIRGraph::~MIRGraph() { 153e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko STLDeleteElements(&block_list_); 1546282dc12440a2072dc06a616160027ff21bd895eIan Rogers STLDeleteElements(&m_units_); 1556282dc12440a2072dc06a616160027ff21bd895eIan Rogers} 1566282dc12440a2072dc06a616160027ff21bd895eIan Rogers 157311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/* 158311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Parse an instruction, return the length of the instruction 159311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 16029a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogersint MIRGraph::ParseInsn(const uint16_t* code_ptr, MIR::DecodedInstruction* decoded_instruction) { 16129a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers const Instruction* inst = Instruction::At(code_ptr); 16229a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers decoded_instruction->opcode = inst->Opcode(); 16329a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers decoded_instruction->vA = inst->HasVRegA() ? inst->VRegA() : 0; 16429a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers decoded_instruction->vB = inst->HasVRegB() ? inst->VRegB() : 0; 16529a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers decoded_instruction->vB_wide = inst->HasWideVRegB() ? inst->WideVRegB() : 0; 16629a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers decoded_instruction->vC = inst->HasVRegC() ? inst->VRegC() : 0; 16729a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers if (inst->HasVarArgs()) { 16829a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers inst->GetVarArgs(decoded_instruction->arg); 16929a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers } 17029a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers return inst->SizeInCodeUnits(); 171311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 172311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 173311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 174311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/* Split an existing block from the specified code offset into two */ 1750d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeBasicBlock* MIRGraph::SplitBlock(DexOffset code_offset, 1762ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom BasicBlock* orig_block, BasicBlock** immed_pred_block_p) { 1770d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DCHECK_GT(code_offset, orig_block->start_offset); 178311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee MIR* insn = orig_block->first_mir_insn; 17933c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski MIR* prev = NULL; // Will be set to instruction before split. 180311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee while (insn) { 181311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (insn->offset == code_offset) break; 1820d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee prev = insn; 183311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee insn = insn->next; 184311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 185311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (insn == NULL) { 186311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee LOG(FATAL) << "Break split failed"; 187311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 18833c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski // Now insn is at the instruction where we want to split, namely 18933c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski // insn will be the first instruction of the "bottom" block. 19033c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski // Similarly, prev will be the last instruction of the "top" block 19133c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski 192e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* bottom_block = CreateNewBB(kDalvikByteCode); 193311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 194311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bottom_block->start_offset = code_offset; 195311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bottom_block->first_mir_insn = insn; 196311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bottom_block->last_mir_insn = orig_block->last_mir_insn; 197311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 19890223cc2e0bfb5a2b55e9ffed896ef327b9f3d2eJunmo Park /* If this block was terminated by a return, conditional branch or throw, 19990223cc2e0bfb5a2b55e9ffed896ef327b9f3d2eJunmo Park * the flag needs to go with the bottom block 20090223cc2e0bfb5a2b55e9ffed896ef327b9f3d2eJunmo Park */ 201311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bottom_block->terminated_by_return = orig_block->terminated_by_return; 202311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee orig_block->terminated_by_return = false; 203311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 20490223cc2e0bfb5a2b55e9ffed896ef327b9f3d2eJunmo Park bottom_block->conditional_branch = orig_block->conditional_branch; 20590223cc2e0bfb5a2b55e9ffed896ef327b9f3d2eJunmo Park orig_block->conditional_branch = false; 20690223cc2e0bfb5a2b55e9ffed896ef327b9f3d2eJunmo Park 20790223cc2e0bfb5a2b55e9ffed896ef327b9f3d2eJunmo Park bottom_block->explicit_throw = orig_block->explicit_throw; 20890223cc2e0bfb5a2b55e9ffed896ef327b9f3d2eJunmo Park orig_block->explicit_throw = false; 20990223cc2e0bfb5a2b55e9ffed896ef327b9f3d2eJunmo Park 210311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* Handle the taken path */ 211311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bottom_block->taken = orig_block->taken; 2120d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (bottom_block->taken != NullBasicBlockId) { 2130d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee orig_block->taken = NullBasicBlockId; 2140d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee BasicBlock* bb_taken = GetBasicBlock(bottom_block->taken); 215e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bb_taken->ErasePredecessor(orig_block->id); 216e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bb_taken->predecessors.push_back(bottom_block->id); 217311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 218311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 219311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* Handle the fallthrough path */ 220311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bottom_block->fall_through = orig_block->fall_through; 2210d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee orig_block->fall_through = bottom_block->id; 222e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bottom_block->predecessors.push_back(orig_block->id); 2230d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (bottom_block->fall_through != NullBasicBlockId) { 2240d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee BasicBlock* bb_fall_through = GetBasicBlock(bottom_block->fall_through); 225e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bb_fall_through->ErasePredecessor(orig_block->id); 226e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bb_fall_through->predecessors.push_back(bottom_block->id); 227311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 228311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 229311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* Handle the successor list */ 2300d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (orig_block->successor_block_list_type != kNotUsed) { 2310d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee bottom_block->successor_block_list_type = orig_block->successor_block_list_type; 232e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bottom_block->successor_blocks.swap(orig_block->successor_blocks); 2330d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee orig_block->successor_block_list_type = kNotUsed; 234e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko DCHECK(orig_block->successor_blocks.empty()); // Empty after the swap() above. 235e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (SuccessorBlockInfo* successor_block_info : bottom_block->successor_blocks) { 2368512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler BasicBlock* bb = GetBasicBlock(successor_block_info->block); 237989367a47b015dd85f850cf756b436fb044b5aeaNiranjan Kumar if (bb != nullptr) { 238e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bb->ErasePredecessor(orig_block->id); 239e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bb->predecessors.push_back(bottom_block->id); 240989367a47b015dd85f850cf756b436fb044b5aeaNiranjan Kumar } 241311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 242311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 243311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 2440d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee orig_block->last_mir_insn = prev; 2453aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler prev->next = nullptr; 246311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 247311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* 248311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Update the immediate predecessor block pointer so that outgoing edges 249311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * can be applied to the proper block. 250311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 251311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (immed_pred_block_p) { 252311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee DCHECK_EQ(*immed_pred_block_p, orig_block); 253311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee *immed_pred_block_p = bottom_block; 254311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 255b48819db07f9a0992a72173380c24249d7fc648abuzbee 256b48819db07f9a0992a72173380c24249d7fc648abuzbee // Associate dex instructions in the bottom block with the new container. 2574376c87eb45b287fad77a16738e76ba28956ab7dVladimir Marko DCHECK(insn != nullptr); 2584376c87eb45b287fad77a16738e76ba28956ab7dVladimir Marko DCHECK(insn != orig_block->first_mir_insn); 2594376c87eb45b287fad77a16738e76ba28956ab7dVladimir Marko DCHECK(insn == bottom_block->first_mir_insn); 2604376c87eb45b287fad77a16738e76ba28956ab7dVladimir Marko DCHECK_EQ(insn->offset, bottom_block->start_offset); 2614376c87eb45b287fad77a16738e76ba28956ab7dVladimir Marko DCHECK(static_cast<int>(insn->dalvikInsn.opcode) == kMirOpCheck || 2622ab40eb3c23559205ac7b9b039bd749458e8a761Jean Christophe Beyler !MIR::DecodedInstruction::IsPseudoMirOp(insn->dalvikInsn.opcode)); 263e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko DCHECK_EQ(dex_pc_to_block_map_[insn->offset], orig_block->id); 26433c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski // Scan the "bottom" instructions, remapping them to the 26533c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski // newly created "bottom" block. 2664376c87eb45b287fad77a16738e76ba28956ab7dVladimir Marko MIR* p = insn; 26733c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski p->bb = bottom_block->id; 268e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko dex_pc_to_block_map_[p->offset] = bottom_block->id; 2694376c87eb45b287fad77a16738e76ba28956ab7dVladimir Marko while (p != bottom_block->last_mir_insn) { 2704376c87eb45b287fad77a16738e76ba28956ab7dVladimir Marko p = p->next; 2714376c87eb45b287fad77a16738e76ba28956ab7dVladimir Marko DCHECK(p != nullptr); 2723aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler p->bb = bottom_block->id; 273b48819db07f9a0992a72173380c24249d7fc648abuzbee int opcode = p->dalvikInsn.opcode; 274b48819db07f9a0992a72173380c24249d7fc648abuzbee /* 275b48819db07f9a0992a72173380c24249d7fc648abuzbee * Some messiness here to ensure that we only enter real opcodes and only the 276b48819db07f9a0992a72173380c24249d7fc648abuzbee * first half of a potentially throwing instruction that has been split into 2774376c87eb45b287fad77a16738e76ba28956ab7dVladimir Marko * CHECK and work portions. Since the 2nd half of a split operation is always 2784376c87eb45b287fad77a16738e76ba28956ab7dVladimir Marko * the first in a BasicBlock, we can't hit it here. 279b48819db07f9a0992a72173380c24249d7fc648abuzbee */ 2802ab40eb3c23559205ac7b9b039bd749458e8a761Jean Christophe Beyler if ((opcode == kMirOpCheck) || !MIR::DecodedInstruction::IsPseudoMirOp(opcode)) { 28133c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski BasicBlockId mapped_id = dex_pc_to_block_map_[p->offset]; 28233c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski // At first glance the instructions should all be mapped to orig_block. 28333c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski // However, multiple instructions may correspond to the same dex, hence an earlier 28433c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski // instruction may have already moved the mapping for dex to bottom_block. 28533c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski DCHECK((mapped_id == orig_block->id) || (mapped_id == bottom_block->id)); 286e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko dex_pc_to_block_map_[p->offset] = bottom_block->id; 287b48819db07f9a0992a72173380c24249d7fc648abuzbee } 288b48819db07f9a0992a72173380c24249d7fc648abuzbee } 289b48819db07f9a0992a72173380c24249d7fc648abuzbee 290311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee return bottom_block; 291311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 292311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 293311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/* 294311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Given a code offset, find out the block that starts with it. If the offset 295311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * is in the middle of an existing block, split it into two. If immed_pred_block_p 296311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * is not non-null and is the block being split, update *immed_pred_block_p to 297311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * point to the bottom block so that outgoing edges can be set up properly 298311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * (by the caller) 299311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Utilizes a map for fast lookup of the typical cases. 300311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 3016a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan RogersBasicBlock* MIRGraph::FindBlock(DexOffset code_offset, bool create, 3022ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom BasicBlock** immed_pred_block_p) { 30309ae022f55ab27edf4802baf7a05e76d7dc823a9Razvan A Lupusoru if (code_offset >= current_code_item_->insns_size_in_code_units_) { 3046a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers return nullptr; 305311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 306b48819db07f9a0992a72173380c24249d7fc648abuzbee 307e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko int block_id = dex_pc_to_block_map_[code_offset]; 308e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* bb = GetBasicBlock(block_id); 309b48819db07f9a0992a72173380c24249d7fc648abuzbee 3106a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers if ((bb != nullptr) && (bb->start_offset == code_offset)) { 311b48819db07f9a0992a72173380c24249d7fc648abuzbee // Does this containing block start with the desired instruction? 312bd663de599b16229085759366c56e2ed5a1dc7ecbuzbee return bb; 313bd663de599b16229085759366c56e2ed5a1dc7ecbuzbee } 314311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 315b48819db07f9a0992a72173380c24249d7fc648abuzbee // No direct hit. 316b48819db07f9a0992a72173380c24249d7fc648abuzbee if (!create) { 3176a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers return nullptr; 318b48819db07f9a0992a72173380c24249d7fc648abuzbee } 319b48819db07f9a0992a72173380c24249d7fc648abuzbee 3206a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers if (bb != nullptr) { 321b48819db07f9a0992a72173380c24249d7fc648abuzbee // The target exists somewhere in an existing block. 3226a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers return SplitBlock(code_offset, bb, bb == *immed_pred_block_p ? immed_pred_block_p : nullptr); 323311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 324311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 325b48819db07f9a0992a72173380c24249d7fc648abuzbee // Create a new block. 326e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bb = CreateNewBB(kDalvikByteCode); 327311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bb->start_offset = code_offset; 328e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko dex_pc_to_block_map_[bb->start_offset] = bb->id; 329311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee return bb; 330311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 331311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 332b48819db07f9a0992a72173380c24249d7fc648abuzbee 333311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/* Identify code range in try blocks and set up the empty catch blocks */ 3342ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MIRGraph::ProcessTryCatchBlocks() { 335311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int tries_size = current_code_item_->tries_size_; 3360d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DexOffset offset; 337311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 338311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (tries_size == 0) { 339311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee return; 340311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 341311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 342311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (int i = 0; i < tries_size; i++) { 343311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee const DexFile::TryItem* pTry = 344311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee DexFile::GetTryItems(*current_code_item_, i); 3450d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DexOffset start_offset = pTry->start_addr_; 3460d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DexOffset end_offset = start_offset + pTry->insn_count_; 347311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (offset = start_offset; offset < end_offset; offset++) { 348862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee try_block_addr_->SetBit(offset); 349311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 350311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 351311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 3528512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Iterate over each of the handlers to enqueue the empty Catch blocks. 35313735955f39b3b304c37d2b2840663c131262c18Ian Rogers const uint8_t* handlers_ptr = DexFile::GetCatchHandlerData(*current_code_item_, 0); 354311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr); 355311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (uint32_t idx = 0; idx < handlers_size; idx++) { 356311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee CatchHandlerIterator iterator(handlers_ptr); 357311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (; iterator.HasNext(); iterator.Next()) { 358311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee uint32_t address = iterator.GetHandlerAddress(); 3596a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers FindBlock(address, true /*create*/, /* immed_pred_block_p */ nullptr); 360311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 361311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee handlers_ptr = iterator.EndDataPointer(); 362311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 363311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 364311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 365e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Markobool MIRGraph::IsBadMonitorExitCatch(NarrowDexOffset monitor_exit_offset, 366e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko NarrowDexOffset catch_offset) { 367e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko // Catches for monitor-exit during stack unwinding have the pattern 368e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko // move-exception (move)* (goto)? monitor-exit throw 369e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko // In the currently generated dex bytecode we see these catching a bytecode range including 370e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko // either its own or an identical monitor-exit, http://b/15745363 . This function checks if 371e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko // it's the case for a given monitor-exit and catch block so that we can ignore it. 372e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko // (We don't want to ignore all monitor-exit catches since one could enclose a synchronized 373e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko // block in a try-block and catch the NPE, Error or Throwable and we should let it through; 374e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko // even though a throwing monitor-exit certainly indicates a bytecode error.) 37509ae022f55ab27edf4802baf7a05e76d7dc823a9Razvan A Lupusoru const Instruction* monitor_exit = Instruction::At(current_code_item_->insns_ + monitor_exit_offset); 376e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko DCHECK(monitor_exit->Opcode() == Instruction::MONITOR_EXIT); 377e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko int monitor_reg = monitor_exit->VRegA_11x(); 37809ae022f55ab27edf4802baf7a05e76d7dc823a9Razvan A Lupusoru const Instruction* check_insn = Instruction::At(current_code_item_->insns_ + catch_offset); 379e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko DCHECK(check_insn->Opcode() == Instruction::MOVE_EXCEPTION); 380e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko if (check_insn->VRegA_11x() == monitor_reg) { 381e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko // Unexpected move-exception to the same register. Probably not the pattern we're looking for. 382e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko return false; 383e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko } 384e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko check_insn = check_insn->Next(); 385e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko while (true) { 386e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko int dest = -1; 387e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko bool wide = false; 388e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko switch (check_insn->Opcode()) { 389e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::MOVE_WIDE: 390e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko wide = true; 391fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers FALLTHROUGH_INTENDED; 392e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::MOVE_OBJECT: 393e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::MOVE: 394e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko dest = check_insn->VRegA_12x(); 395e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko break; 396e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko 397e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::MOVE_WIDE_FROM16: 398e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko wide = true; 399fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers FALLTHROUGH_INTENDED; 400e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::MOVE_OBJECT_FROM16: 401e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::MOVE_FROM16: 402e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko dest = check_insn->VRegA_22x(); 403e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko break; 404e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko 405e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::MOVE_WIDE_16: 406e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko wide = true; 407fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers FALLTHROUGH_INTENDED; 408e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::MOVE_OBJECT_16: 409e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::MOVE_16: 410e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko dest = check_insn->VRegA_32x(); 411e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko break; 412e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko 413e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::GOTO: 414e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::GOTO_16: 415e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::GOTO_32: 416e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko check_insn = check_insn->RelativeAt(check_insn->GetTargetOffset()); 417fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers FALLTHROUGH_INTENDED; 418e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko default: 419e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko return check_insn->Opcode() == Instruction::MONITOR_EXIT && 420e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko check_insn->VRegA_11x() == monitor_reg; 421e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko } 422e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko 423e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko if (dest == monitor_reg || (wide && dest + 1 == monitor_reg)) { 424e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko return false; 425e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko } 426e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko 427e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko check_insn = check_insn->Next(); 428e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko } 429e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko} 430e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko 431311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/* Process instructions with the kBranch flag */ 4320d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeBasicBlock* MIRGraph::ProcessCanBranch(BasicBlock* cur_block, MIR* insn, DexOffset cur_offset, 4330d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee int width, int flags, const uint16_t* code_ptr, 4342ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom const uint16_t* code_end) { 4350d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DexOffset target = cur_offset; 436311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee switch (insn->dalvikInsn.opcode) { 437311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::GOTO: 438311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::GOTO_16: 439311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::GOTO_32: 440311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee target += insn->dalvikInsn.vA; 441311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee break; 442311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_EQ: 443311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_NE: 444311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_LT: 445311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_GE: 446311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_GT: 447311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_LE: 448311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cur_block->conditional_branch = true; 449311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee target += insn->dalvikInsn.vC; 450311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee break; 451311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_EQZ: 452311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_NEZ: 453311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_LTZ: 454311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_GEZ: 455311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_GTZ: 456311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_LEZ: 457311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cur_block->conditional_branch = true; 458311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee target += insn->dalvikInsn.vB; 459311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee break; 460311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee default: 461311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee LOG(FATAL) << "Unexpected opcode(" << insn->dalvikInsn.opcode << ") with kBranch set"; 462311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 463b48819db07f9a0992a72173380c24249d7fc648abuzbee CountBranch(target); 4646a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers BasicBlock* taken_block = FindBlock(target, /* create */ true, 465311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* immed_pred_block_p */ &cur_block); 4660d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee cur_block->taken = taken_block->id; 467e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko taken_block->predecessors.push_back(cur_block->id); 468311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 469311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* Always terminate the current block for conditional branches */ 470311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (flags & Instruction::kContinue) { 4712469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler BasicBlock* fallthrough_block = FindBlock(cur_offset + width, 472311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* create */ 473311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee true, 474311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* immed_pred_block_p */ 475311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee &cur_block); 4760d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee cur_block->fall_through = fallthrough_block->id; 477e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko fallthrough_block->predecessors.push_back(cur_block->id); 478311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } else if (code_ptr < code_end) { 4796a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers FindBlock(cur_offset + width, /* create */ true, /* immed_pred_block_p */ nullptr); 480311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 481311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee return cur_block; 482311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 483311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 484311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/* Process instructions with the kSwitch flag */ 48517189ac098b2f156713db1821b49db7b2f018bbebuzbeeBasicBlock* MIRGraph::ProcessCanSwitch(BasicBlock* cur_block, MIR* insn, DexOffset cur_offset, 48617189ac098b2f156713db1821b49db7b2f018bbebuzbee int width, int flags) { 4876a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers UNUSED(flags); 488311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee const uint16_t* switch_data = 489311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee reinterpret_cast<const uint16_t*>(GetCurrentInsns() + cur_offset + insn->dalvikInsn.vB); 490311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int size; 491311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee const int* keyTable; 492311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee const int* target_table; 493311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int i; 494311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int first_key; 495311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 496311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* 497311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Packed switch data format: 498311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * ushort ident = 0x0100 magic value 499311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * ushort size number of entries in the table 500311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * int first_key first (and lowest) switch case value 501311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * int targets[size] branch targets, relative to switch opcode 502311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * 503311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Total size is (4+size*2) 16-bit code units. 504311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 505311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (insn->dalvikInsn.opcode == Instruction::PACKED_SWITCH) { 506311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee DCHECK_EQ(static_cast<int>(switch_data[0]), 507311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee static_cast<int>(Instruction::kPackedSwitchSignature)); 508311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee size = switch_data[1]; 509311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee first_key = switch_data[2] | (switch_data[3] << 16); 510311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee target_table = reinterpret_cast<const int*>(&switch_data[4]); 5118512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler keyTable = NULL; // Make the compiler happy. 512311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* 513311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Sparse switch data format: 514311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * ushort ident = 0x0200 magic value 515311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * ushort size number of entries in the table; > 0 516311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * int keys[size] keys, sorted low-to-high; 32-bit aligned 517311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * int targets[size] branch targets, relative to switch opcode 518311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * 519311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Total size is (2+size*4) 16-bit code units. 520311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 521311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } else { 522311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee DCHECK_EQ(static_cast<int>(switch_data[0]), 523311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee static_cast<int>(Instruction::kSparseSwitchSignature)); 524311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee size = switch_data[1]; 525311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee keyTable = reinterpret_cast<const int*>(&switch_data[2]); 526311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee target_table = reinterpret_cast<const int*>(&switch_data[2 + size*2]); 5278512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler first_key = 0; // To make the compiler happy. 528311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 529311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 5300d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (cur_block->successor_block_list_type != kNotUsed) { 531311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee LOG(FATAL) << "Successor block list already in use: " 5320d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee << static_cast<int>(cur_block->successor_block_list_type); 533311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 5340d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee cur_block->successor_block_list_type = 5350d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee (insn->dalvikInsn.opcode == Instruction::PACKED_SWITCH) ? kPackedSwitch : kSparseSwitch; 536e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko cur_block->successor_blocks.reserve(size); 537311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 538311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (i = 0; i < size; i++) { 5396a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers BasicBlock* case_block = FindBlock(cur_offset + target_table[i], /* create */ true, 5406a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers /* immed_pred_block_p */ &cur_block); 5418512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler SuccessorBlockInfo* successor_block_info = 542f6c4b3ba3825de1dbb3e747a68b809c6cc8eb4dbMathieu Chartier static_cast<SuccessorBlockInfo*>(arena_->Alloc(sizeof(SuccessorBlockInfo), 54383cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko kArenaAllocSuccessor)); 5440d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee successor_block_info->block = case_block->id; 545311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee successor_block_info->key = 546311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee (insn->dalvikInsn.opcode == Instruction::PACKED_SWITCH) ? 547311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee first_key + i : keyTable[i]; 548e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko cur_block->successor_blocks.push_back(successor_block_info); 549e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko case_block->predecessors.push_back(cur_block->id); 550311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 551311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 552311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* Fall-through case */ 5536a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers BasicBlock* fallthrough_block = FindBlock(cur_offset + width, /* create */ true, 5546a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers /* immed_pred_block_p */ nullptr); 5550d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee cur_block->fall_through = fallthrough_block->id; 556e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko fallthrough_block->predecessors.push_back(cur_block->id); 55717189ac098b2f156713db1821b49db7b2f018bbebuzbee return cur_block; 558311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 559311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 560311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/* Process instructions with the kThrow flag */ 5610d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeBasicBlock* MIRGraph::ProcessCanThrow(BasicBlock* cur_block, MIR* insn, DexOffset cur_offset, 5620d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee int width, int flags, ArenaBitVector* try_block_addr, 5632ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom const uint16_t* code_ptr, const uint16_t* code_end) { 5646a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers UNUSED(flags); 565862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee bool in_try_block = try_block_addr->IsBitSet(cur_offset); 56617189ac098b2f156713db1821b49db7b2f018bbebuzbee bool is_throw = (insn->dalvikInsn.opcode == Instruction::THROW); 567311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 568311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* In try block */ 569311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (in_try_block) { 570311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee CatchHandlerIterator iterator(*current_code_item_, cur_offset); 571311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 5720d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (cur_block->successor_block_list_type != kNotUsed) { 573311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee LOG(INFO) << PrettyMethod(cu_->method_idx, *cu_->dex_file); 574311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee LOG(FATAL) << "Successor block list already in use: " 5750d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee << static_cast<int>(cur_block->successor_block_list_type); 576311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 577311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 57802c8cc6d1312a2b55533f02f6369dc7c94672f90Brian Carlstrom for (; iterator.HasNext(); iterator.Next()) { 5796a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers BasicBlock* catch_block = FindBlock(iterator.GetHandlerAddress(), false /* create */, 5806a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers nullptr /* immed_pred_block_p */); 581e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko if (insn->dalvikInsn.opcode == Instruction::MONITOR_EXIT && 582e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko IsBadMonitorExitCatch(insn->offset, catch_block->start_offset)) { 583e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko // Don't allow monitor-exit to catch its own exception, http://b/15745363 . 584e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko continue; 585e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko } 586e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko if (cur_block->successor_block_list_type == kNotUsed) { 587e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko cur_block->successor_block_list_type = kCatch; 588e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko } 589311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee catch_block->catch_entry = true; 590311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (kIsDebugBuild) { 591311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee catches_.insert(catch_block->start_offset); 592311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 5938512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler SuccessorBlockInfo* successor_block_info = reinterpret_cast<SuccessorBlockInfo*> 59483cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko (arena_->Alloc(sizeof(SuccessorBlockInfo), kArenaAllocSuccessor)); 5950d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee successor_block_info->block = catch_block->id; 596311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee successor_block_info->key = iterator.GetHandlerTypeIndex(); 597e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko cur_block->successor_blocks.push_back(successor_block_info); 598e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko catch_block->predecessors.push_back(cur_block->id); 599311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 600e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko in_try_block = (cur_block->successor_block_list_type != kNotUsed); 601e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko } 602e767f6ce3997f7634b26e7651bc7b90c060d3965Vladimir Marko bool build_all_edges = 603e767f6ce3997f7634b26e7651bc7b90c060d3965Vladimir Marko (cu_->disable_opt & (1 << kSuppressExceptionEdges)) || is_throw || in_try_block; 604e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko if (!in_try_block && build_all_edges) { 605e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* eh_block = CreateNewBB(kExceptionHandling); 6060d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee cur_block->taken = eh_block->id; 607311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee eh_block->start_offset = cur_offset; 608e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko eh_block->predecessors.push_back(cur_block->id); 609311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 610311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 61117189ac098b2f156713db1821b49db7b2f018bbebuzbee if (is_throw) { 612311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cur_block->explicit_throw = true; 6132724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee if (code_ptr < code_end) { 6148512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Force creation of new block following THROW via side-effect. 6156a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers FindBlock(cur_offset + width, /* create */ true, /* immed_pred_block_p */ nullptr); 616311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 617311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (!in_try_block) { 618311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee // Don't split a THROW that can't rethrow - we're done. 619311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee return cur_block; 620311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 621311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 622311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 62317189ac098b2f156713db1821b49db7b2f018bbebuzbee if (!build_all_edges) { 62417189ac098b2f156713db1821b49db7b2f018bbebuzbee /* 62517189ac098b2f156713db1821b49db7b2f018bbebuzbee * Even though there is an exception edge here, control cannot return to this 62617189ac098b2f156713db1821b49db7b2f018bbebuzbee * method. Thus, for the purposes of dataflow analysis and optimization, we can 62717189ac098b2f156713db1821b49db7b2f018bbebuzbee * ignore the edge. Doing this reduces compile time, and increases the scope 62817189ac098b2f156713db1821b49db7b2f018bbebuzbee * of the basic-block level optimization pass. 62917189ac098b2f156713db1821b49db7b2f018bbebuzbee */ 63017189ac098b2f156713db1821b49db7b2f018bbebuzbee return cur_block; 63117189ac098b2f156713db1821b49db7b2f018bbebuzbee } 63217189ac098b2f156713db1821b49db7b2f018bbebuzbee 633311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* 634311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Split the potentially-throwing instruction into two parts. 635311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * The first half will be a pseudo-op that captures the exception 636311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * edges and terminates the basic block. It always falls through. 637311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Then, create a new basic block that begins with the throwing instruction 638311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * (minus exceptions). Note: this new basic block must NOT be entered into 639311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * the block_map. If the potentially-throwing instruction is the target of a 640311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * future branch, we need to find the check psuedo half. The new 641311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * basic block containing the work portion of the instruction should 642311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * only be entered via fallthrough from the block containing the 643311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * pseudo exception edge MIR. Note also that this new block is 644311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * not automatically terminated after the work portion, and may 645311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * contain following instructions. 646b48819db07f9a0992a72173380c24249d7fc648abuzbee * 647b48819db07f9a0992a72173380c24249d7fc648abuzbee * Note also that the dex_pc_to_block_map_ entry for the potentially 648b48819db07f9a0992a72173380c24249d7fc648abuzbee * throwing instruction will refer to the original basic block. 649311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 650e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* new_block = CreateNewBB(kDalvikByteCode); 651311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee new_block->start_offset = insn->offset; 6520d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee cur_block->fall_through = new_block->id; 653e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko new_block->predecessors.push_back(cur_block->id); 6543aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler MIR* new_insn = NewMIR(); 655311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee *new_insn = *insn; 65635ba7f3a78d38885ec54e61ed060d2771eeceea7buzbee insn->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpCheck); 6578512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Associate the two halves. 658311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee insn->meta.throw_insn = new_insn; 659cdacac4a8196bdc620185079ec9e886329606f3dJean Christophe Beyler new_block->AppendMIR(new_insn); 660311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee return new_block; 661311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 662311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 663311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/* Parse a Dex method and insert it into the MIRGraph at the current insert point. */ 664311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeevoid MIRGraph::InlineMethod(const DexFile::CodeItem* code_item, uint32_t access_flags, 6658b2c0b9abc3f520495f4387ea040132ba85cae69Ian Rogers InvokeType invoke_type, uint16_t class_def_idx, 6662ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom uint32_t method_idx, jobject class_loader, const DexFile& dex_file) { 667311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee current_code_item_ = code_item; 668311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee method_stack_.push_back(std::make_pair(current_method_, current_offset_)); 669311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee current_method_ = m_units_.size(); 670311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee current_offset_ = 0; 671311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee // TODO: will need to snapshot stack image and use that as the mir context identification. 672311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee m_units_.push_back(new DexCompilationUnit(cu_, class_loader, Runtime::Current()->GetClassLinker(), 6732730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko dex_file, current_code_item_, class_def_idx, method_idx, access_flags, 6742730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Marko cu_->compiler_driver->GetVerifiedMethod(&dex_file, method_idx))); 675311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee const uint16_t* code_ptr = current_code_item_->insns_; 676311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee const uint16_t* code_end = 677311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee current_code_item_->insns_ + current_code_item_->insns_size_in_code_units_; 678311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 679311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee // TODO: need to rework expansion of block list & try_block_addr when inlining activated. 680b48819db07f9a0992a72173380c24249d7fc648abuzbee // TUNING: use better estimate of basic blocks for following resize. 681e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko block_list_.reserve(block_list_.size() + current_code_item_->insns_size_in_code_units_); 682e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko dex_pc_to_block_map_.resize(dex_pc_to_block_map_.size() + current_code_item_->insns_size_in_code_units_); 683bd663de599b16229085759366c56e2ed5a1dc7ecbuzbee 684311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee // TODO: replace with explicit resize routine. Using automatic extension side effect for now. 685862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee try_block_addr_->SetBit(current_code_item_->insns_size_in_code_units_); 686862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee try_block_addr_->ClearBit(current_code_item_->insns_size_in_code_units_); 687311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 688311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee // If this is the first method, set up default entry and exit blocks. 689311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (current_method_ == 0) { 690311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee DCHECK(entry_block_ == NULL); 691311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee DCHECK(exit_block_ == NULL); 6924439596b00c91f565370bf0813cc2f9165093693Andreas Gampe DCHECK_EQ(num_blocks_, 0U); 6930d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // Use id 0 to represent a null block. 694e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* null_block = CreateNewBB(kNullBlock); 6950d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DCHECK_EQ(null_block->id, NullBasicBlockId); 6960d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee null_block->hidden = true; 697e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko entry_block_ = CreateNewBB(kEntryBlock); 698e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko exit_block_ = CreateNewBB(kExitBlock); 699311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee // TODO: deprecate all "cu->" fields; move what's left to wherever CompilationUnit is allocated. 700311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cu_->dex_file = &dex_file; 701311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cu_->class_def_idx = class_def_idx; 702311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cu_->method_idx = method_idx; 703311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cu_->access_flags = access_flags; 704311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cu_->invoke_type = invoke_type; 705311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cu_->shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx)); 706311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } else { 707311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee UNIMPLEMENTED(FATAL) << "Nested inlining not implemented."; 708311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* 709311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Will need to manage storage for ins & outs, push prevous state and update 710311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * insert point. 711311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 712311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 713311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 714311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* Current block to record parsed instructions */ 715e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* cur_block = CreateNewBB(kDalvikByteCode); 7160d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DCHECK_EQ(current_offset_, 0U); 717311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cur_block->start_offset = current_offset_; 7180d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // TODO: for inlining support, insert at the insert point rather than entry block. 7190d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee entry_block_->fall_through = cur_block->id; 720e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko cur_block->predecessors.push_back(entry_block_->id); 721311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 7223d73ba2ce682edfaf41f29521bd6039c6499a1c5Vladimir Marko /* Identify code range in try blocks and set up the empty catch blocks */ 723311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee ProcessTryCatchBlocks(); 724311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 7253d73ba2ce682edfaf41f29521bd6039c6499a1c5Vladimir Marko uint64_t merged_df_flags = 0u; 7263d73ba2ce682edfaf41f29521bd6039c6499a1c5Vladimir Marko 727311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* Parse all instructions and put them into containing basic blocks */ 728311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee while (code_ptr < code_end) { 7293aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler MIR *insn = NewMIR(); 730311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee insn->offset = current_offset_; 731311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee insn->m_unit_index = current_method_; 732311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int width = ParseInsn(code_ptr, &insn->dalvikInsn); 733311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee Instruction::Code opcode = insn->dalvikInsn.opcode; 734311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (opcode_count_ != NULL) { 735311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee opcode_count_[static_cast<int>(opcode)]++; 736311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 737311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 738fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler int flags = insn->dalvikInsn.FlagsOf(); 739b1f1d642093418612c0a27ce4203b421bb6eb767buzbee int verify_flags = Instruction::VerifyFlagsOf(insn->dalvikInsn.opcode); 740311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 741cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler uint64_t df_flags = GetDataFlowAttributes(insn); 7423d73ba2ce682edfaf41f29521bd6039c6499a1c5Vladimir Marko merged_df_flags |= df_flags; 743311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 744311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (df_flags & DF_HAS_DEFS) { 745311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee def_count_ += (df_flags & DF_A_WIDE) ? 2 : 1; 746311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 747311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 7481da1e2fceb0030b4b76b43510b1710a9613e0c2ebuzbee if (df_flags & DF_LVN) { 7491da1e2fceb0030b4b76b43510b1710a9613e0c2ebuzbee cur_block->use_lvn = true; // Run local value numbering on this basic block. 7501da1e2fceb0030b4b76b43510b1710a9613e0c2ebuzbee } 7511da1e2fceb0030b4b76b43510b1710a9613e0c2ebuzbee 7528512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Check for inline data block signatures. 7532724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee if (opcode == Instruction::NOP) { 7542724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee // A simple NOP will have a width of 1 at this point, embedded data NOP > 1. 7552724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee if ((width == 1) && ((current_offset_ & 0x1) == 0x1) && ((code_end - code_ptr) > 1)) { 7562724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee // Could be an aligning nop. If an embedded data NOP follows, treat pair as single unit. 7572724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee uint16_t following_raw_instruction = code_ptr[1]; 7582724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee if ((following_raw_instruction == Instruction::kSparseSwitchSignature) || 7592724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee (following_raw_instruction == Instruction::kPackedSwitchSignature) || 7602724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee (following_raw_instruction == Instruction::kArrayDataSignature)) { 7612724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee width += Instruction::At(code_ptr + 1)->SizeInCodeUnits(); 7622724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee } 7632724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee } 7642724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee if (width == 1) { 7652724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee // It is a simple nop - treat normally. 766cdacac4a8196bdc620185079ec9e886329606f3dJean Christophe Beyler cur_block->AppendMIR(insn); 7672724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee } else { 7680d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DCHECK(cur_block->fall_through == NullBasicBlockId); 7690d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DCHECK(cur_block->taken == NullBasicBlockId); 7702724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee // Unreachable instruction, mark for no continuation. 7712724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee flags &= ~Instruction::kContinue; 7722724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee } 7732724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee } else { 774cdacac4a8196bdc620185079ec9e886329606f3dJean Christophe Beyler cur_block->AppendMIR(insn); 7752724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee } 7762724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee 777b48819db07f9a0992a72173380c24249d7fc648abuzbee // Associate the starting dex_pc for this opcode with its containing basic block. 778e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko dex_pc_to_block_map_[insn->offset] = cur_block->id; 779b48819db07f9a0992a72173380c24249d7fc648abuzbee 7802724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee code_ptr += width; 7812724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee 782311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (flags & Instruction::kBranch) { 783311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cur_block = ProcessCanBranch(cur_block, insn, current_offset_, 784311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee width, flags, code_ptr, code_end); 785311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } else if (flags & Instruction::kReturn) { 786311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cur_block->terminated_by_return = true; 7870d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee cur_block->fall_through = exit_block_->id; 788e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko exit_block_->predecessors.push_back(cur_block->id); 789311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* 790311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Terminate the current block if there are instructions 791311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * afterwards. 792311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 793311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (code_ptr < code_end) { 794311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* 795311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Create a fallthrough block for real instructions 796311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * (incl. NOP). 797311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 7986a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers FindBlock(current_offset_ + width, /* create */ true, /* immed_pred_block_p */ nullptr); 799311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 800311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } else if (flags & Instruction::kThrow) { 801311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cur_block = ProcessCanThrow(cur_block, insn, current_offset_, width, flags, try_block_addr_, 802311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee code_ptr, code_end); 803311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } else if (flags & Instruction::kSwitch) { 80417189ac098b2f156713db1821b49db7b2f018bbebuzbee cur_block = ProcessCanSwitch(cur_block, insn, current_offset_, width, flags); 805311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 806688e7c5c9f36573dd4da2edd889470d930b0054bAlexei Zavjalov if (verify_flags & Instruction::kVerifyVarArgRange || 807688e7c5c9f36573dd4da2edd889470d930b0054bAlexei Zavjalov verify_flags & Instruction::kVerifyVarArgRangeNonZero) { 808b1f1d642093418612c0a27ce4203b421bb6eb767buzbee /* 809b1f1d642093418612c0a27ce4203b421bb6eb767buzbee * The Quick backend's runtime model includes a gap between a method's 810b1f1d642093418612c0a27ce4203b421bb6eb767buzbee * argument ("in") vregs and the rest of its vregs. Handling a range instruction 811b1f1d642093418612c0a27ce4203b421bb6eb767buzbee * which spans the gap is somewhat complicated, and should not happen 812b1f1d642093418612c0a27ce4203b421bb6eb767buzbee * in normal usage of dx. Punt to the interpreter. 813b1f1d642093418612c0a27ce4203b421bb6eb767buzbee */ 814b1f1d642093418612c0a27ce4203b421bb6eb767buzbee int first_reg_in_range = insn->dalvikInsn.vC; 815b1f1d642093418612c0a27ce4203b421bb6eb767buzbee int last_reg_in_range = first_reg_in_range + insn->dalvikInsn.vA - 1; 816b1f1d642093418612c0a27ce4203b421bb6eb767buzbee if (IsInVReg(first_reg_in_range) != IsInVReg(last_reg_in_range)) { 817b1f1d642093418612c0a27ce4203b421bb6eb767buzbee punt_to_interpreter_ = true; 818b1f1d642093418612c0a27ce4203b421bb6eb767buzbee } 819b1f1d642093418612c0a27ce4203b421bb6eb767buzbee } 820311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee current_offset_ += width; 8216a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers BasicBlock* next_block = FindBlock(current_offset_, /* create */ false, 8226a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers /* immed_pred_block_p */ nullptr); 823311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (next_block) { 824311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* 825311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * The next instruction could be the target of a previously parsed 826311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * forward branch so a block is already created. If the current 827311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * instruction is not an unconditional branch, connect them through 828311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * the fall-through link. 829311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 8300d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DCHECK(cur_block->fall_through == NullBasicBlockId || 8310d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee GetBasicBlock(cur_block->fall_through) == next_block || 8320d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee GetBasicBlock(cur_block->fall_through) == exit_block_); 833311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 8340d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if ((cur_block->fall_through == NullBasicBlockId) && (flags & Instruction::kContinue)) { 8350d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee cur_block->fall_through = next_block->id; 836e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko next_block->predecessors.push_back(cur_block->id); 837311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 838311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cur_block = next_block; 839311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 840311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 8413d73ba2ce682edfaf41f29521bd6039c6499a1c5Vladimir Marko merged_df_flags_ = merged_df_flags; 8425816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko 843311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (cu_->enable_debug & (1 << kDebugDumpCFG)) { 844311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee DumpCFG("/sdcard/1_post_parse_cfg/", true); 845311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 846311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 847311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (cu_->verbose) { 8481fd3346740dfb7f47be9922312b68a4227fada96buzbee DumpMIRGraph(); 849311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 850311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 851311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 8522ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MIRGraph::ShowOpcodeStats() { 853311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee DCHECK(opcode_count_ != NULL); 854311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee LOG(INFO) << "Opcode Count"; 855311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (int i = 0; i < kNumPackedOpcodes; i++) { 856311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (opcode_count_[i] != 0) { 857311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee LOG(INFO) << "-C- " << Instruction::Name(static_cast<Instruction::Code>(i)) 858311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee << " " << opcode_count_[i]; 859311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 860311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 861311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 862311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 863cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyleruint64_t MIRGraph::GetDataFlowAttributes(Instruction::Code opcode) { 864cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler DCHECK_LT((size_t) opcode, (sizeof(oat_data_flow_attributes_) / sizeof(oat_data_flow_attributes_[0]))); 865cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler return oat_data_flow_attributes_[opcode]; 866cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler} 867cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler 868cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyleruint64_t MIRGraph::GetDataFlowAttributes(MIR* mir) { 869cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler DCHECK(mir != nullptr); 870cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler Instruction::Code opcode = mir->dalvikInsn.opcode; 871cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler return GetDataFlowAttributes(opcode); 872cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler} 873cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler 874311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee// TODO: use a configurable base prefix, and adjust callers to supply pass name. 875311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/* Dump the CFG into a DOT graph */ 876d0a515562772d7c637160e8779c4f253ee169c3aJean Christophe Beylervoid MIRGraph::DumpCFG(const char* dir_prefix, bool all_blocks, const char *suffix) { 877311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee FILE* file; 878a8869e60d93ba9eed36a5b53553b7609f58fc05bJean Christophe Beyler static AtomicInteger cnt(0); 879a8869e60d93ba9eed36a5b53553b7609f58fc05bJean Christophe Beyler 880a8869e60d93ba9eed36a5b53553b7609f58fc05bJean Christophe Beyler // Increment counter to get a unique file number. 881a8869e60d93ba9eed36a5b53553b7609f58fc05bJean Christophe Beyler cnt++; 882a8869e60d93ba9eed36a5b53553b7609f58fc05bJean Christophe Beyler 883311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee std::string fname(PrettyMethod(cu_->method_idx, *cu_->dex_file)); 884311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee ReplaceSpecialChars(fname); 885a8869e60d93ba9eed36a5b53553b7609f58fc05bJean Christophe Beyler fname = StringPrintf("%s%s%x%s_%d.dot", dir_prefix, fname.c_str(), 886d0a515562772d7c637160e8779c4f253ee169c3aJean Christophe Beyler GetBasicBlock(GetEntryBlock()->fall_through)->start_offset, 887a8869e60d93ba9eed36a5b53553b7609f58fc05bJean Christophe Beyler suffix == nullptr ? "" : suffix, 888a8869e60d93ba9eed36a5b53553b7609f58fc05bJean Christophe Beyler cnt.LoadRelaxed()); 889311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee file = fopen(fname.c_str(), "w"); 890311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (file == NULL) { 891311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee return; 892311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 893311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, "digraph G {\n"); 894311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 895311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " rankdir=TB\n"); 896311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 897311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int num_blocks = all_blocks ? GetNumBlocks() : num_reachable_blocks_; 898311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int idx; 899311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 900311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (idx = 0; idx < num_blocks; idx++) { 901e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko int block_idx = all_blocks ? idx : dfs_order_[idx]; 9028512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler BasicBlock* bb = GetBasicBlock(block_idx); 90325bc279080a56546b0f8a33342a853b2778eed0dRazvan A Lupusoru if (bb == NULL) continue; 904311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (bb->block_type == kDead) continue; 905a8869e60d93ba9eed36a5b53553b7609f58fc05bJean Christophe Beyler if (bb->hidden) continue; 906311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (bb->block_type == kEntryBlock) { 907311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " entry_%d [shape=Mdiamond];\n", bb->id); 908311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } else if (bb->block_type == kExitBlock) { 909311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " exit_%d [shape=Mdiamond];\n", bb->id); 910311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } else if (bb->block_type == kDalvikByteCode) { 911311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " block%04x_%d [shape=record,label = \"{ \\\n", 912311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bb->start_offset, bb->id); 9138512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler const MIR* mir; 914311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " {block id %d\\l}%s\\\n", bb->id, 915311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bb->first_mir_insn ? " | " : " "); 916311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (mir = bb->first_mir_insn; mir; mir = mir->next) { 917311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int opcode = mir->dalvikInsn.opcode; 91866c6d7bdfdd535e6ecf4461bba3804f1a7794fcdVladimir Marko fprintf(file, " {%04x %s %s %s %s %s %s %s %s\\l}%s\\\n", mir->offset, 919d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell mir->ssa_rep ? GetDalvikDisassembly(mir) : 9202ab40eb3c23559205ac7b9b039bd749458e8a761Jean Christophe Beyler !MIR::DecodedInstruction::IsPseudoMirOp(opcode) ? 9212ab40eb3c23559205ac7b9b039bd749458e8a761Jean Christophe Beyler Instruction::Name(mir->dalvikInsn.opcode) : 922d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell extended_mir_op_names_[opcode - kMirOpFirst], 923d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell (mir->optimization_flags & MIR_IGNORE_RANGE_CHECK) != 0 ? " no_rangecheck" : " ", 924d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell (mir->optimization_flags & MIR_IGNORE_NULL_CHECK) != 0 ? " no_nullcheck" : " ", 92560bfe7b3e8f00f0a8ef3f5d8716adfdf86b71f43Udayan Banerji (mir->optimization_flags & MIR_IGNORE_SUSPEND_CHECK) != 0 ? " no_suspendcheck" : " ", 926b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler (mir->optimization_flags & MIR_STORE_NON_TEMPORAL) != 0 ? " non_temporal" : " ", 9271500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru (mir->optimization_flags & MIR_CALLEE) != 0 ? " inlined" : " ", 92866c6d7bdfdd535e6ecf4461bba3804f1a7794fcdVladimir Marko (mir->optimization_flags & MIR_CLASS_IS_INITIALIZED) != 0 ? " cl_inited" : " ", 92966c6d7bdfdd535e6ecf4461bba3804f1a7794fcdVladimir Marko (mir->optimization_flags & MIR_CLASS_IS_IN_DEX_CACHE) != 0 ? " cl_in_cache" : " ", 930d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell mir->next ? " | " : " "); 931311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 932311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " }\"];\n\n"); 933311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } else if (bb->block_type == kExceptionHandling) { 934311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee char block_name[BLOCK_NAME_LEN]; 935311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 936311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee GetBlockName(bb, block_name); 937311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " %s [shape=invhouse];\n", block_name); 938311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 939311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 940311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee char block_name1[BLOCK_NAME_LEN], block_name2[BLOCK_NAME_LEN]; 941311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 9420d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (bb->taken != NullBasicBlockId) { 943311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee GetBlockName(bb, block_name1); 9440d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee GetBlockName(GetBasicBlock(bb->taken), block_name2); 945311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " %s:s -> %s:n [style=dotted]\n", 946311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee block_name1, block_name2); 947311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 9480d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (bb->fall_through != NullBasicBlockId) { 949311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee GetBlockName(bb, block_name1); 9500d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee GetBlockName(GetBasicBlock(bb->fall_through), block_name2); 951311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " %s:s -> %s:n\n", block_name1, block_name2); 952311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 953311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 9540d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (bb->successor_block_list_type != kNotUsed) { 955311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " succ%04x_%d [shape=%s,label = \"{ \\\n", 956311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bb->start_offset, bb->id, 9570d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee (bb->successor_block_list_type == kCatch) ? "Mrecord" : "record"); 958311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 959e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko int last_succ_id = static_cast<int>(bb->successor_blocks.size() - 1u); 960311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int succ_id = 0; 961e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (SuccessorBlockInfo* successor_block_info : bb->successor_blocks) { 9628512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler BasicBlock* dest_block = GetBasicBlock(successor_block_info->block); 963311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " {<f%d> %04x: %04x\\l}%s\\\n", 964e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko succ_id, 965311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee successor_block_info->key, 966311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee dest_block->start_offset, 967e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko (succ_id != last_succ_id) ? " | " : " "); 968e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko ++succ_id; 969311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 970311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " }\"];\n\n"); 971311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 972311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee GetBlockName(bb, block_name1); 973311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " %s:s -> succ%04x_%d:n [style=dashed]\n", 974311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee block_name1, bb->start_offset, bb->id); 975311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 97625bc279080a56546b0f8a33342a853b2778eed0dRazvan A Lupusoru // Link the successor pseudo-block with all of its potential targets. 97725bc279080a56546b0f8a33342a853b2778eed0dRazvan A Lupusoru succ_id = 0; 978e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (SuccessorBlockInfo* successor_block_info : bb->successor_blocks) { 97925bc279080a56546b0f8a33342a853b2778eed0dRazvan A Lupusoru BasicBlock* dest_block = GetBasicBlock(successor_block_info->block); 980311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 98125bc279080a56546b0f8a33342a853b2778eed0dRazvan A Lupusoru GetBlockName(dest_block, block_name2); 98225bc279080a56546b0f8a33342a853b2778eed0dRazvan A Lupusoru fprintf(file, " succ%04x_%d:f%d:e -> %s:n\n", bb->start_offset, 98325bc279080a56546b0f8a33342a853b2778eed0dRazvan A Lupusoru bb->id, succ_id++, block_name2); 984311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 985311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 986311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, "\n"); 987311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 988311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (cu_->verbose) { 989311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* Display the dominator tree */ 990311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee GetBlockName(bb, block_name1); 991311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " cfg%s [label=\"%s\", shape=none];\n", 992311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee block_name1, block_name1); 993311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (bb->i_dom) { 9940d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee GetBlockName(GetBasicBlock(bb->i_dom), block_name2); 995311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " cfg%s:s -> cfg%s:n\n\n", block_name2, block_name1); 996311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 997311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 998311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 999311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, "}\n"); 1000311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fclose(file); 1001311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 1002311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 10033aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler/* Insert an MIR instruction to the end of a basic block. */ 1004cdacac4a8196bdc620185079ec9e886329606f3dJean Christophe Beylervoid BasicBlock::AppendMIR(MIR* mir) { 10058512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Insert it after the last MIR. 10068512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler InsertMIRListAfter(last_mir_insn, mir, mir); 10078512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 10088512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 10098512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylervoid BasicBlock::AppendMIRList(MIR* first_list_mir, MIR* last_list_mir) { 10108512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Insert it after the last MIR. 10118512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler InsertMIRListAfter(last_mir_insn, first_list_mir, last_list_mir); 10128512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 10138512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 10148512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylervoid BasicBlock::AppendMIRList(const std::vector<MIR*>& insns) { 10158512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler for (std::vector<MIR*>::const_iterator it = insns.begin(); it != insns.end(); it++) { 10168512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler MIR* new_mir = *it; 10178512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 10188512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Add a copy of each MIR. 10198512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler InsertMIRListAfter(last_mir_insn, new_mir, new_mir); 10208512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 10218512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 10228512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 10238512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler/* Insert a MIR instruction after the specified MIR. */ 10248512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylervoid BasicBlock::InsertMIRAfter(MIR* current_mir, MIR* new_mir) { 10258512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler InsertMIRListAfter(current_mir, new_mir, new_mir); 10268512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 10278512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 10288512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylervoid BasicBlock::InsertMIRListAfter(MIR* insert_after, MIR* first_list_mir, MIR* last_list_mir) { 10298512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // If no MIR, we are done. 10308512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (first_list_mir == nullptr || last_list_mir == nullptr) { 10318512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return; 10328512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 10338512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 10348512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // If insert_after is null, assume BB is empty. 10358512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (insert_after == nullptr) { 10368512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler first_mir_insn = first_list_mir; 10378512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_mir_insn = last_list_mir; 10388512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_list_mir->next = nullptr; 10391fd3346740dfb7f47be9922312b68a4227fada96buzbee } else { 10408512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler MIR* after_list = insert_after->next; 10418512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler insert_after->next = first_list_mir; 10428512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_list_mir->next = after_list; 10438512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (after_list == nullptr) { 10448512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_mir_insn = last_list_mir; 10458512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 10461fd3346740dfb7f47be9922312b68a4227fada96buzbee } 10473aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 10488512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Set this BB to be the basic block of the MIRs. 10498512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler MIR* last = last_list_mir->next; 10508512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler for (MIR* mir = first_list_mir; mir != last; mir = mir->next) { 10518512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler mir->bb = id; 10528512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 10531fd3346740dfb7f47be9922312b68a4227fada96buzbee} 10541fd3346740dfb7f47be9922312b68a4227fada96buzbee 10553aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler/* Insert an MIR instruction to the head of a basic block. */ 1056cdacac4a8196bdc620185079ec9e886329606f3dJean Christophe Beylervoid BasicBlock::PrependMIR(MIR* mir) { 10578512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler InsertMIRListBefore(first_mir_insn, mir, mir); 10588512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 10593aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 10608512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylervoid BasicBlock::PrependMIRList(MIR* first_list_mir, MIR* last_list_mir) { 10618512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Insert it before the first MIR. 10628512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler InsertMIRListBefore(first_mir_insn, first_list_mir, last_list_mir); 10631fd3346740dfb7f47be9922312b68a4227fada96buzbee} 10641fd3346740dfb7f47be9922312b68a4227fada96buzbee 10658512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylervoid BasicBlock::PrependMIRList(const std::vector<MIR*>& to_add) { 10668512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler for (std::vector<MIR*>::const_iterator it = to_add.begin(); it != to_add.end(); it++) { 10678512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler MIR* mir = *it; 10681fd3346740dfb7f47be9922312b68a4227fada96buzbee 10698512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler InsertMIRListBefore(first_mir_insn, mir, mir); 10701fd3346740dfb7f47be9922312b68a4227fada96buzbee } 10718512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 10723aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 10738512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler/* Insert a MIR instruction before the specified MIR. */ 10748512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylervoid BasicBlock::InsertMIRBefore(MIR* current_mir, MIR* new_mir) { 10758512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Insert as a single element list. 10768512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return InsertMIRListBefore(current_mir, new_mir, new_mir); 10773aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler} 10783aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 10793aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe BeylerMIR* BasicBlock::FindPreviousMIR(MIR* mir) { 10803aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler MIR* current = first_mir_insn; 10813aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 10823aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler while (current != nullptr) { 10833aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler MIR* next = current->next; 10843aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 10853aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler if (next == mir) { 10863aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler return current; 10873aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler } 10883aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 10893aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler current = next; 10903aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler } 10913aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 10923aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler return nullptr; 10933aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler} 10943aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 10958512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylervoid BasicBlock::InsertMIRListBefore(MIR* insert_before, MIR* first_list_mir, MIR* last_list_mir) { 10968512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // If no MIR, we are done. 10978512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (first_list_mir == nullptr || last_list_mir == nullptr) { 10988512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return; 10998512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 11008512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 11018512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // If insert_before is null, assume BB is empty. 11028512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (insert_before == nullptr) { 11038512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler first_mir_insn = first_list_mir; 11048512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_mir_insn = last_list_mir; 11058512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_list_mir->next = nullptr; 11068512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } else { 11078512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (first_mir_insn == insert_before) { 11088512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_list_mir->next = first_mir_insn; 11098512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler first_mir_insn = first_list_mir; 11108512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } else { 11118512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Find the preceding MIR. 11128512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler MIR* before_list = FindPreviousMIR(insert_before); 11138512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler DCHECK(before_list != nullptr); 11148512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler before_list->next = first_list_mir; 11158512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_list_mir->next = insert_before; 11168512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 11178512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 11188512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 11198512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Set this BB to be the basic block of the MIRs. 11208512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler for (MIR* mir = first_list_mir; mir != last_list_mir->next; mir = mir->next) { 11218512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler mir->bb = id; 11223aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler } 11238512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 11248512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 11258512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylerbool BasicBlock::RemoveMIR(MIR* mir) { 11268512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Remove as a single element list. 11278512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return RemoveMIRList(mir, mir); 11288512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 11298512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 11308512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylerbool BasicBlock::RemoveMIRList(MIR* first_list_mir, MIR* last_list_mir) { 11318512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (first_list_mir == nullptr) { 11328512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return false; 11338512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 11348512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 11358512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Try to find the MIR. 11368512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler MIR* before_list = nullptr; 11378512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler MIR* after_list = nullptr; 11383aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 11398512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // If we are removing from the beginning of the MIR list. 11408512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (first_mir_insn == first_list_mir) { 11418512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler before_list = nullptr; 11428512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } else { 11438512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler before_list = FindPreviousMIR(first_list_mir); 11448512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (before_list == nullptr) { 11458512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // We did not find the mir. 11468512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return false; 11478512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 11488512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 11498512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 1150a4307aca310aac0ac62dcb5435daa02b1f950558Jean Christophe Beyler // Remove the BB information and also find the after_list. 1151590c6a4ded1deb378baa253c86070d8eeffdc820Chao-ying Fu for (MIR* mir = first_list_mir; mir != last_list_mir->next; mir = mir->next) { 11528512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler mir->bb = NullBasicBlockId; 11538512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 11548512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 11558512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler after_list = last_list_mir->next; 11568512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 1157a4307aca310aac0ac62dcb5435daa02b1f950558Jean Christophe Beyler // If there is nothing before the list, after_list is the first_mir. 11588512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (before_list == nullptr) { 11598512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler first_mir_insn = after_list; 1160a4307aca310aac0ac62dcb5435daa02b1f950558Jean Christophe Beyler } else { 1161a4307aca310aac0ac62dcb5435daa02b1f950558Jean Christophe Beyler before_list->next = after_list; 11628512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 11633aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 1164a4307aca310aac0ac62dcb5435daa02b1f950558Jean Christophe Beyler // If there is nothing after the list, before_list is last_mir. 11658512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (after_list == nullptr) { 11668512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_mir_insn = before_list; 11673aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler } 11688512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 11698512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return true; 11701fd3346740dfb7f47be9922312b68a4227fada96buzbee} 11711fd3346740dfb7f47be9922312b68a4227fada96buzbee 1172cdacac4a8196bdc620185079ec9e886329606f3dJean Christophe BeylerMIR* BasicBlock::GetNextUnconditionalMir(MIRGraph* mir_graph, MIR* current) { 11733bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru MIR* next_mir = nullptr; 11743bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru 11753bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru if (current != nullptr) { 11763bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru next_mir = current->next; 11773bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru } 11783bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru 11793bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru if (next_mir == nullptr) { 11803bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru // Only look for next MIR that follows unconditionally. 1181cdacac4a8196bdc620185079ec9e886329606f3dJean Christophe Beyler if ((taken == NullBasicBlockId) && (fall_through != NullBasicBlockId)) { 1182cdacac4a8196bdc620185079ec9e886329606f3dJean Christophe Beyler next_mir = mir_graph->GetBasicBlock(fall_through)->first_mir_insn; 11833bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru } 11843bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru } 11853bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru 11863bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru return next_mir; 11873bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru} 11883bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru 11891500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusorustatic void FillTypeSizeString(uint32_t type_size, std::string* decoded_mir) { 11901500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru DCHECK(decoded_mir != nullptr); 11911500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru OpSize type = static_cast<OpSize>(type_size >> 16); 11921500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru uint16_t vect_size = (type_size & 0xFFFF); 11931500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru 11941500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru // Now print the type and vector size. 11951500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru std::stringstream ss; 11961500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru ss << " (type:"; 11971500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru ss << type; 11981500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru ss << " vectsize:"; 11991500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru ss << vect_size; 12001500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru ss << ")"; 12011500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru 12021500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(ss.str()); 12031500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru} 12041500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru 12051500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoruvoid MIRGraph::DisassembleExtendedInstr(const MIR* mir, std::string* decoded_mir) { 12061500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru DCHECK(decoded_mir != nullptr); 12071500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru int opcode = mir->dalvikInsn.opcode; 12081500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru SSARepresentation* ssa_rep = mir->ssa_rep; 12091500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru int defs = (ssa_rep != nullptr) ? ssa_rep->num_defs : 0; 12101500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru int uses = (ssa_rep != nullptr) ? ssa_rep->num_uses : 0; 12111500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru 1212f41b92c7a2fcdd411b9edd7070e4729ea18e0ba6Vladimir if (opcode < kMirOpFirst) { 1213f41b92c7a2fcdd411b9edd7070e4729ea18e0ba6Vladimir return; // It is not an extended instruction. 1214f41b92c7a2fcdd411b9edd7070e4729ea18e0ba6Vladimir } 1215f41b92c7a2fcdd411b9edd7070e4729ea18e0ba6Vladimir 12161500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(extended_mir_op_names_[opcode - kMirOpFirst]); 12171500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru 12181500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru switch (opcode) { 12191500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPhi: { 12201500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (defs > 0 && uses > 0) { 12211500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru BasicBlockId* incoming = mir->meta.phi_incoming; 12221500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" %s = (%s", 12231500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru GetSSANameWithConst(ssa_rep->defs[0], true).c_str(), 12241500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru GetSSANameWithConst(ssa_rep->uses[0], true).c_str())); 12251500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(":%d", incoming[0])); 12261500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru for (int i = 1; i < uses; i++) { 12271500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(", %s:%d", GetSSANameWithConst(ssa_rep->uses[i], true).c_str(), incoming[i])); 12281500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 12291500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(")"); 12301500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 12311500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 12321500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 12331500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpCopy: 12341500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (ssa_rep != nullptr) { 12351500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(" "); 12361500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[0], false)); 12371500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (defs > 1) { 12381500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(", "); 12391500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[1], false)); 12401500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 12411500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(" = "); 12421500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->uses[0], false)); 12431500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (uses > 1) { 12441500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(", "); 12451500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->uses[1], false)); 12461500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 12471500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } else { 12481500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" v%d = v%d", mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 12491500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 12501500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 12511500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpFusedCmplFloat: 12521500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpFusedCmpgFloat: 12531500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpFusedCmplDouble: 12541500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpFusedCmpgDouble: 12551500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpFusedCmpLong: 12561500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (ssa_rep != nullptr) { 12571500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(" "); 12581500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->uses[0], false)); 12591500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru for (int i = 1; i < uses; i++) { 12601500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(", "); 12611500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->uses[i], false)); 12621500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 12631500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } else { 12641500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" v%d, v%d", mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 12651500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 12661500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 12671500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpMoveVector: 12681500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 12691500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 12701500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 12711500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedAddition: 12721500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d + vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 12731500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 12741500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 12751500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedMultiply: 12761500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d * vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 12771500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 12781500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 12791500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedSubtract: 12801500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d - vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 12811500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 12821500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 12831500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedAnd: 12841500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d & vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 12851500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 12861500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 12871500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedOr: 12881500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d \\| vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 12891500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 12901500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 12911500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedXor: 12921500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d ^ vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 12931500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 12941500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 12951500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedShiftLeft: 12961500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d \\<\\< %d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 12971500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 12981500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 12991500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedUnsignedShiftRight: 13001500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d \\>\\>\\> %d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 13011500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 13021500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13031500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedSignedShiftRight: 13041500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d \\>\\> %d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 13051500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 13061500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13071500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpConstVector: 13081500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = %x, %x, %x, %x", mir->dalvikInsn.vA, mir->dalvikInsn.arg[0], 13091500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru mir->dalvikInsn.arg[1], mir->dalvikInsn.arg[2], mir->dalvikInsn.arg[3])); 13101500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13111500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedSet: 13121500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (ssa_rep != nullptr) { 13131500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = %s", mir->dalvikInsn.vA, 13141500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru GetSSANameWithConst(ssa_rep->uses[0], false).c_str())); 13151500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (uses > 1) { 13161500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(", "); 13171500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->uses[1], false)); 13181500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 13191500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } else { 13201500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = v%d", mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 13211500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 13221500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 13231500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13241500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedAddReduce: 13251500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (ssa_rep != nullptr) { 13261500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(" "); 13271500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[0], false)); 13281500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (defs > 1) { 13291500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(", "); 13301500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[1], false)); 13311500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 13321500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" = vect%d + %s", mir->dalvikInsn.vB, 13331500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru GetSSANameWithConst(ssa_rep->uses[0], false).c_str())); 13341500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (uses > 1) { 13351500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(", "); 13361500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->uses[1], false)); 13371500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 13381500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } else { 13391500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf("v%d = vect%d + v%d", mir->dalvikInsn.vA, mir->dalvikInsn.vB, mir->dalvikInsn.vA)); 13401500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 13411500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 13421500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13431500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedReduce: 13441500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (ssa_rep != nullptr) { 13451500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(" "); 13461500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[0], false)); 13471500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (defs > 1) { 13481500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(", "); 13491500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[1], false)); 13501500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 1351b72c723bfb21e05cb9b0a7999db805df93fcaee8Razvan A Lupusoru decoded_mir->append(StringPrintf(" = vect%d (extr_idx:%d)", mir->dalvikInsn.vB, mir->dalvikInsn.arg[0])); 13521500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } else { 1353b72c723bfb21e05cb9b0a7999db805df93fcaee8Razvan A Lupusoru decoded_mir->append(StringPrintf(" v%d = vect%d (extr_idx:%d)", mir->dalvikInsn.vA, 1354b72c723bfb21e05cb9b0a7999db805df93fcaee8Razvan A Lupusoru mir->dalvikInsn.vB, mir->dalvikInsn.arg[0])); 13551500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 13561500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 13571500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13581500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpReserveVectorRegisters: 13591500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpReturnVectorRegisters: 13601500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d - vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 13611500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13621500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpMemBarrier: { 13631500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(" type:"); 13641500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru std::stringstream ss; 13651500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru ss << static_cast<MemBarrierKind>(mir->dalvikInsn.vA); 13661500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(ss.str()); 13671500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13681500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 1369b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A case kMirOpPackedArrayGet: 1370b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A case kMirOpPackedArrayPut: 1371b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A decoded_mir->append(StringPrintf(" vect%d", mir->dalvikInsn.vA)); 1372b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A if (ssa_rep != nullptr) { 1373b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A decoded_mir->append(StringPrintf(", %s[%s]", 1374b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A GetSSANameWithConst(ssa_rep->uses[0], false).c_str(), 1375b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A GetSSANameWithConst(ssa_rep->uses[1], false).c_str())); 1376b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A } else { 1377b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A decoded_mir->append(StringPrintf(", v%d[v%d]", mir->dalvikInsn.vB, mir->dalvikInsn.vC)); 1378b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A } 1379b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A FillTypeSizeString(mir->dalvikInsn.arg[0], decoded_mir); 1380b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A break; 13811500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru default: 13821500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13831500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 13841500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru} 13851500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru 13862ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromchar* MIRGraph::GetDalvikDisassembly(const MIR* mir) { 138729a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers MIR::DecodedInstruction insn = mir->dalvikInsn; 13881fd3346740dfb7f47be9922312b68a4227fada96buzbee std::string str; 13891fd3346740dfb7f47be9922312b68a4227fada96buzbee int flags = 0; 13901fd3346740dfb7f47be9922312b68a4227fada96buzbee int opcode = insn.opcode; 13911fd3346740dfb7f47be9922312b68a4227fada96buzbee char* ret; 13921fd3346740dfb7f47be9922312b68a4227fada96buzbee bool nop = false; 13931fd3346740dfb7f47be9922312b68a4227fada96buzbee SSARepresentation* ssa_rep = mir->ssa_rep; 13948512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler Instruction::Format dalvik_format = Instruction::k10x; // Default to no-operand format. 13951fd3346740dfb7f47be9922312b68a4227fada96buzbee 13961500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru // Handle special cases that recover the original dalvik instruction. 13971fd3346740dfb7f47be9922312b68a4227fada96buzbee if ((opcode == kMirOpCheck) || (opcode == kMirOpCheckPart2)) { 13981fd3346740dfb7f47be9922312b68a4227fada96buzbee str.append(extended_mir_op_names_[opcode - kMirOpFirst]); 13991fd3346740dfb7f47be9922312b68a4227fada96buzbee str.append(": "); 14008512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Recover the original Dex instruction. 14011fd3346740dfb7f47be9922312b68a4227fada96buzbee insn = mir->meta.throw_insn->dalvikInsn; 14021fd3346740dfb7f47be9922312b68a4227fada96buzbee ssa_rep = mir->meta.throw_insn->ssa_rep; 14031fd3346740dfb7f47be9922312b68a4227fada96buzbee opcode = insn.opcode; 14041fd3346740dfb7f47be9922312b68a4227fada96buzbee } else if (opcode == kMirOpNop) { 14051fd3346740dfb7f47be9922312b68a4227fada96buzbee str.append("["); 1406750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru if (mir->offset < current_code_item_->insns_size_in_code_units_) { 1407750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru // Recover original opcode. 1408750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru insn.opcode = Instruction::At(current_code_item_->insns_ + mir->offset)->Opcode(); 1409750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru opcode = insn.opcode; 1410750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru } 14111fd3346740dfb7f47be9922312b68a4227fada96buzbee nop = true; 14121fd3346740dfb7f47be9922312b68a4227fada96buzbee } 14130f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov int defs = (ssa_rep != NULL) ? ssa_rep->num_defs : 0; 14140f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov int uses = (ssa_rep != NULL) ? ssa_rep->num_uses : 0; 14151fd3346740dfb7f47be9922312b68a4227fada96buzbee 14162ab40eb3c23559205ac7b9b039bd749458e8a761Jean Christophe Beyler if (MIR::DecodedInstruction::IsPseudoMirOp(opcode)) { 14171500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru // Note that this does not check the MIR's opcode in all cases. In cases where it 14181500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru // recovered dalvik instruction, it uses opcode of that instead of the extended one. 14191500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru DisassembleExtendedInstr(mir, &str); 14201fd3346740dfb7f47be9922312b68a4227fada96buzbee } else { 14211fd3346740dfb7f47be9922312b68a4227fada96buzbee dalvik_format = Instruction::FormatOf(insn.opcode); 1422fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler flags = insn.FlagsOf(); 14231fd3346740dfb7f47be9922312b68a4227fada96buzbee str.append(Instruction::Name(insn.opcode)); 14241fd3346740dfb7f47be9922312b68a4227fada96buzbee 14258512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // For invokes-style formats, treat wide regs as a pair of singles. 14261fd3346740dfb7f47be9922312b68a4227fada96buzbee bool show_singles = ((dalvik_format == Instruction::k35c) || 14271fd3346740dfb7f47be9922312b68a4227fada96buzbee (dalvik_format == Instruction::k3rc)); 14281fd3346740dfb7f47be9922312b68a4227fada96buzbee if (defs != 0) { 14291500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(" "); 14301500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(GetSSANameWithConst(ssa_rep->defs[0], false)); 14311500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (defs > 1) { 14321500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(", "); 14331500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(GetSSANameWithConst(ssa_rep->defs[1], false)); 14341500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 14351fd3346740dfb7f47be9922312b68a4227fada96buzbee if (uses != 0) { 14361fd3346740dfb7f47be9922312b68a4227fada96buzbee str.append(", "); 14371fd3346740dfb7f47be9922312b68a4227fada96buzbee } 14381fd3346740dfb7f47be9922312b68a4227fada96buzbee } 14391fd3346740dfb7f47be9922312b68a4227fada96buzbee for (int i = 0; i < uses; i++) { 14401500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(" "); 14411500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(GetSSANameWithConst(ssa_rep->uses[i], show_singles)); 14421fd3346740dfb7f47be9922312b68a4227fada96buzbee if (!show_singles && (reg_location_ != NULL) && reg_location_[i].wide) { 14431fd3346740dfb7f47be9922312b68a4227fada96buzbee // For the listing, skip the high sreg. 14441fd3346740dfb7f47be9922312b68a4227fada96buzbee i++; 14451fd3346740dfb7f47be9922312b68a4227fada96buzbee } 14461500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (i != (uses - 1)) { 14471fd3346740dfb7f47be9922312b68a4227fada96buzbee str.append(","); 14481fd3346740dfb7f47be9922312b68a4227fada96buzbee } 14491fd3346740dfb7f47be9922312b68a4227fada96buzbee } 14501500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru 14511fd3346740dfb7f47be9922312b68a4227fada96buzbee switch (dalvik_format) { 14528512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler case Instruction::k11n: // Add one immediate from vB. 14531fd3346740dfb7f47be9922312b68a4227fada96buzbee case Instruction::k21s: 14541fd3346740dfb7f47be9922312b68a4227fada96buzbee case Instruction::k31i: 14551fd3346740dfb7f47be9922312b68a4227fada96buzbee case Instruction::k21h: 14561500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(StringPrintf(", #0x%x", insn.vB)); 14571fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 14588512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler case Instruction::k51l: // Add one wide immediate. 145923b03b5b5fdaa517eda3b8b358752672cf6046b1Ian Rogers str.append(StringPrintf(", #%" PRId64, insn.vB_wide)); 14601fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 14618512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler case Instruction::k21c: // One register, one string/type/method index. 14621fd3346740dfb7f47be9922312b68a4227fada96buzbee case Instruction::k31c: 14631500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(StringPrintf(", index #0x%x", insn.vB)); 14641fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 14658512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler case Instruction::k22c: // Two registers, one string/type/method index. 14661500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(StringPrintf(", index #0x%x", insn.vC)); 14671fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 14688512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler case Instruction::k22s: // Add one immediate from vC. 14691fd3346740dfb7f47be9922312b68a4227fada96buzbee case Instruction::k22b: 14701500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(StringPrintf(", #0x%x", insn.vC)); 14711fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 14721500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru default: 14738512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Nothing left to print. 14741500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 147502c8cc6d1312a2b55533f02f6369dc7c94672f90Brian Carlstrom } 14761500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru 14770f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov if ((flags & Instruction::kBranch) != 0) { 14780f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov // For branches, decode the instructions to print out the branch targets. 14790f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov int offset = 0; 14800f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov switch (dalvik_format) { 14810f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov case Instruction::k21t: 14820f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov offset = insn.vB; 14830f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov break; 14840f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov case Instruction::k22t: 14850f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov offset = insn.vC; 14860f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov break; 14870f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov case Instruction::k10t: 14880f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov case Instruction::k20t: 14890f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov case Instruction::k30t: 14900f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov offset = insn.vA; 14910f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov break; 14920f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov default: 14930f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov LOG(FATAL) << "Unexpected branch format " << dalvik_format << " from " << insn.opcode; 14941500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 14950f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov } 14961500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(StringPrintf(", 0x%x (%c%x)", mir->offset + offset, 14970f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov offset > 0 ? '+' : '-', offset > 0 ? offset : -offset)); 14980f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov } 14991500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru 15001500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (nop) { 15011500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append("]--optimized away"); 15021500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 15031fd3346740dfb7f47be9922312b68a4227fada96buzbee } 15041fd3346740dfb7f47be9922312b68a4227fada96buzbee int length = str.length() + 1; 150583cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko ret = static_cast<char*>(arena_->Alloc(length, kArenaAllocDFInfo)); 15061fd3346740dfb7f47be9922312b68a4227fada96buzbee strncpy(ret, str.c_str(), length); 15071fd3346740dfb7f47be9922312b68a4227fada96buzbee return ret; 15081fd3346740dfb7f47be9922312b68a4227fada96buzbee} 15091fd3346740dfb7f47be9922312b68a4227fada96buzbee 15101fd3346740dfb7f47be9922312b68a4227fada96buzbee/* Turn method name into a legal Linux file name */ 15112ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MIRGraph::ReplaceSpecialChars(std::string& str) { 15129b7085a4e7c40e7fa01932ea1647a4a33ac1c585Brian Carlstrom static const struct { const char before; const char after; } match[] = { 15139b7085a4e7c40e7fa01932ea1647a4a33ac1c585Brian Carlstrom {'/', '-'}, {';', '#'}, {' ', '#'}, {'$', '+'}, 15149b7085a4e7c40e7fa01932ea1647a4a33ac1c585Brian Carlstrom {'(', '@'}, {')', '@'}, {'<', '='}, {'>', '='} 15159b7085a4e7c40e7fa01932ea1647a4a33ac1c585Brian Carlstrom }; 15161fd3346740dfb7f47be9922312b68a4227fada96buzbee for (unsigned int i = 0; i < sizeof(match)/sizeof(match[0]); i++) { 15171fd3346740dfb7f47be9922312b68a4227fada96buzbee std::replace(str.begin(), str.end(), match[i].before, match[i].after); 15181fd3346740dfb7f47be9922312b68a4227fada96buzbee } 15191fd3346740dfb7f47be9922312b68a4227fada96buzbee} 15201fd3346740dfb7f47be9922312b68a4227fada96buzbee 15212ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromstd::string MIRGraph::GetSSAName(int ssa_reg) { 152239ebcb800aabedd0ffa6aa4aeac8aa4194c66e61Ian Rogers // TODO: This value is needed for LLVM and debugging. Currently, we compute this and then copy to 152339ebcb800aabedd0ffa6aa4aeac8aa4194c66e61Ian Rogers // the arena. We should be smarter and just place straight into the arena, or compute the 152439ebcb800aabedd0ffa6aa4aeac8aa4194c66e61Ian Rogers // value more lazily. 15251500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru int vreg = SRegToVReg(ssa_reg); 15261500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (vreg >= static_cast<int>(GetFirstTempVR())) { 15271500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru return StringPrintf("t%d_%d", SRegToVReg(ssa_reg), GetSSASubscript(ssa_reg)); 15281500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } else { 15291500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru return StringPrintf("v%d_%d", SRegToVReg(ssa_reg), GetSSASubscript(ssa_reg)); 15301500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 15311fd3346740dfb7f47be9922312b68a4227fada96buzbee} 15321fd3346740dfb7f47be9922312b68a4227fada96buzbee 15331fd3346740dfb7f47be9922312b68a4227fada96buzbee// Similar to GetSSAName, but if ssa name represents an immediate show that as well. 15342ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromstd::string MIRGraph::GetSSANameWithConst(int ssa_reg, bool singles_only) { 15351fd3346740dfb7f47be9922312b68a4227fada96buzbee if (reg_location_ == NULL) { 15368512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Pre-SSA - just use the standard name. 15371fd3346740dfb7f47be9922312b68a4227fada96buzbee return GetSSAName(ssa_reg); 15381fd3346740dfb7f47be9922312b68a4227fada96buzbee } 15391fd3346740dfb7f47be9922312b68a4227fada96buzbee if (IsConst(reg_location_[ssa_reg])) { 15409944b3b792103cb72df1953b5502ced9bf128305Mark Mendell if (!singles_only && reg_location_[ssa_reg].wide && 15419944b3b792103cb72df1953b5502ced9bf128305Mark Mendell !reg_location_[ssa_reg].high_word) { 154223b03b5b5fdaa517eda3b8b358752672cf6046b1Ian Rogers return StringPrintf("v%d_%d#0x%" PRIx64, SRegToVReg(ssa_reg), GetSSASubscript(ssa_reg), 15431fd3346740dfb7f47be9922312b68a4227fada96buzbee ConstantValueWide(reg_location_[ssa_reg])); 15441fd3346740dfb7f47be9922312b68a4227fada96buzbee } else { 1545b1eba213afaf7fa6445de863ddc9680ab99762eaBrian Carlstrom return StringPrintf("v%d_%d#0x%x", SRegToVReg(ssa_reg), GetSSASubscript(ssa_reg), 15461fd3346740dfb7f47be9922312b68a4227fada96buzbee ConstantValue(reg_location_[ssa_reg])); 15471fd3346740dfb7f47be9922312b68a4227fada96buzbee } 15481fd3346740dfb7f47be9922312b68a4227fada96buzbee } else { 15491500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru int vreg = SRegToVReg(ssa_reg); 15501500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (vreg >= static_cast<int>(GetFirstTempVR())) { 15511500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru return StringPrintf("t%d_%d", SRegToVReg(ssa_reg), GetSSASubscript(ssa_reg)); 15521500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } else { 15531500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru return StringPrintf("v%d_%d", SRegToVReg(ssa_reg), GetSSASubscript(ssa_reg)); 15541500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 15551fd3346740dfb7f47be9922312b68a4227fada96buzbee } 15561fd3346740dfb7f47be9922312b68a4227fada96buzbee} 15571fd3346740dfb7f47be9922312b68a4227fada96buzbee 15582ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MIRGraph::GetBlockName(BasicBlock* bb, char* name) { 15591fd3346740dfb7f47be9922312b68a4227fada96buzbee switch (bb->block_type) { 15601fd3346740dfb7f47be9922312b68a4227fada96buzbee case kEntryBlock: 15611fd3346740dfb7f47be9922312b68a4227fada96buzbee snprintf(name, BLOCK_NAME_LEN, "entry_%d", bb->id); 15621fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 15631fd3346740dfb7f47be9922312b68a4227fada96buzbee case kExitBlock: 15641fd3346740dfb7f47be9922312b68a4227fada96buzbee snprintf(name, BLOCK_NAME_LEN, "exit_%d", bb->id); 15651fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 15661fd3346740dfb7f47be9922312b68a4227fada96buzbee case kDalvikByteCode: 15671fd3346740dfb7f47be9922312b68a4227fada96buzbee snprintf(name, BLOCK_NAME_LEN, "block%04x_%d", bb->start_offset, bb->id); 15681fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 15691fd3346740dfb7f47be9922312b68a4227fada96buzbee case kExceptionHandling: 15701fd3346740dfb7f47be9922312b68a4227fada96buzbee snprintf(name, BLOCK_NAME_LEN, "exception%04x_%d", bb->start_offset, 15711fd3346740dfb7f47be9922312b68a4227fada96buzbee bb->id); 15721fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 15731fd3346740dfb7f47be9922312b68a4227fada96buzbee default: 15741fd3346740dfb7f47be9922312b68a4227fada96buzbee snprintf(name, BLOCK_NAME_LEN, "_%d", bb->id); 15751fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 15761fd3346740dfb7f47be9922312b68a4227fada96buzbee } 15771fd3346740dfb7f47be9922312b68a4227fada96buzbee} 15781fd3346740dfb7f47be9922312b68a4227fada96buzbee 15792ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromconst char* MIRGraph::GetShortyFromTargetIdx(int target_idx) { 15800d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // TODO: for inlining support, use current code unit. 15811fd3346740dfb7f47be9922312b68a4227fada96buzbee const DexFile::MethodId& method_id = cu_->dex_file->GetMethodId(target_idx); 15821fd3346740dfb7f47be9922312b68a4227fada96buzbee return cu_->dex_file->GetShorty(method_id.proto_idx_); 15831fd3346740dfb7f47be9922312b68a4227fada96buzbee} 15841fd3346740dfb7f47be9922312b68a4227fada96buzbee 15851fd3346740dfb7f47be9922312b68a4227fada96buzbee/* Debug Utility - dump a compilation unit */ 15862ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MIRGraph::DumpMIRGraph() { 15871fd3346740dfb7f47be9922312b68a4227fada96buzbee const char* block_type_names[] = { 158817189ac098b2f156713db1821b49db7b2f018bbebuzbee "Null Block", 15891fd3346740dfb7f47be9922312b68a4227fada96buzbee "Entry Block", 15901fd3346740dfb7f47be9922312b68a4227fada96buzbee "Code Block", 15911fd3346740dfb7f47be9922312b68a4227fada96buzbee "Exit Block", 15921fd3346740dfb7f47be9922312b68a4227fada96buzbee "Exception Handling", 15931fd3346740dfb7f47be9922312b68a4227fada96buzbee "Catch Block" 15941fd3346740dfb7f47be9922312b68a4227fada96buzbee }; 15951fd3346740dfb7f47be9922312b68a4227fada96buzbee 15961fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "Compiling " << PrettyMethod(cu_->method_idx, *cu_->dex_file); 15978d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru LOG(INFO) << GetInsns(0) << " insns"; 15981fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << GetNumBlocks() << " blocks in total"; 15991fd3346740dfb7f47be9922312b68a4227fada96buzbee 1600e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (BasicBlock* bb : block_list_) { 16011fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << StringPrintf("Block %d (%s) (insn %04x - %04x%s)", 16021fd3346740dfb7f47be9922312b68a4227fada96buzbee bb->id, 16031fd3346740dfb7f47be9922312b68a4227fada96buzbee block_type_names[bb->block_type], 16041fd3346740dfb7f47be9922312b68a4227fada96buzbee bb->start_offset, 16051fd3346740dfb7f47be9922312b68a4227fada96buzbee bb->last_mir_insn ? bb->last_mir_insn->offset : bb->start_offset, 16061fd3346740dfb7f47be9922312b68a4227fada96buzbee bb->last_mir_insn ? "" : " empty"); 16070d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (bb->taken != NullBasicBlockId) { 16080d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee LOG(INFO) << " Taken branch: block " << bb->taken 16090d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee << "(0x" << std::hex << GetBasicBlock(bb->taken)->start_offset << ")"; 16101fd3346740dfb7f47be9922312b68a4227fada96buzbee } 16110d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (bb->fall_through != NullBasicBlockId) { 16120d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee LOG(INFO) << " Fallthrough : block " << bb->fall_through 16130d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee << " (0x" << std::hex << GetBasicBlock(bb->fall_through)->start_offset << ")"; 16141fd3346740dfb7f47be9922312b68a4227fada96buzbee } 16151fd3346740dfb7f47be9922312b68a4227fada96buzbee } 16161fd3346740dfb7f47be9922312b68a4227fada96buzbee} 16171fd3346740dfb7f47be9922312b68a4227fada96buzbee 16181fd3346740dfb7f47be9922312b68a4227fada96buzbee/* 16191fd3346740dfb7f47be9922312b68a4227fada96buzbee * Build an array of location records for the incoming arguments. 16201fd3346740dfb7f47be9922312b68a4227fada96buzbee * Note: one location record per word of arguments, with dummy 16211fd3346740dfb7f47be9922312b68a4227fada96buzbee * high-word loc for wide arguments. Also pull up any following 16221fd3346740dfb7f47be9922312b68a4227fada96buzbee * MOVE_RESULT and incorporate it into the invoke. 16231fd3346740dfb7f47be9922312b68a4227fada96buzbee */ 16241fd3346740dfb7f47be9922312b68a4227fada96buzbeeCallInfo* MIRGraph::NewMemCallInfo(BasicBlock* bb, MIR* mir, InvokeType type, 16252ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom bool is_range) { 1626f6c4b3ba3825de1dbb3e747a68b809c6cc8eb4dbMathieu Chartier CallInfo* info = static_cast<CallInfo*>(arena_->Alloc(sizeof(CallInfo), 162783cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko kArenaAllocMisc)); 16281fd3346740dfb7f47be9922312b68a4227fada96buzbee MIR* move_result_mir = FindMoveResult(bb, mir); 16291fd3346740dfb7f47be9922312b68a4227fada96buzbee if (move_result_mir == NULL) { 16301fd3346740dfb7f47be9922312b68a4227fada96buzbee info->result.location = kLocInvalid; 16311fd3346740dfb7f47be9922312b68a4227fada96buzbee } else { 16321fd3346740dfb7f47be9922312b68a4227fada96buzbee info->result = GetRawDest(move_result_mir); 16331fd3346740dfb7f47be9922312b68a4227fada96buzbee move_result_mir->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop); 16341fd3346740dfb7f47be9922312b68a4227fada96buzbee } 16351fd3346740dfb7f47be9922312b68a4227fada96buzbee info->num_arg_words = mir->ssa_rep->num_uses; 16361fd3346740dfb7f47be9922312b68a4227fada96buzbee info->args = (info->num_arg_words == 0) ? NULL : static_cast<RegLocation*> 163783cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko (arena_->Alloc(sizeof(RegLocation) * info->num_arg_words, kArenaAllocMisc)); 16381fd3346740dfb7f47be9922312b68a4227fada96buzbee for (int i = 0; i < info->num_arg_words; i++) { 16391fd3346740dfb7f47be9922312b68a4227fada96buzbee info->args[i] = GetRawSrc(mir, i); 16401fd3346740dfb7f47be9922312b68a4227fada96buzbee } 16411fd3346740dfb7f47be9922312b68a4227fada96buzbee info->opt_flags = mir->optimization_flags; 16421fd3346740dfb7f47be9922312b68a4227fada96buzbee info->type = type; 16431fd3346740dfb7f47be9922312b68a4227fada96buzbee info->is_range = is_range; 16441fd3346740dfb7f47be9922312b68a4227fada96buzbee info->index = mir->dalvikInsn.vB; 16451fd3346740dfb7f47be9922312b68a4227fada96buzbee info->offset = mir->offset; 1646f096aad9203d7c50b2f9cbe1c1215a50c265a059Vladimir Marko info->mir = mir; 16471fd3346740dfb7f47be9922312b68a4227fada96buzbee return info; 16481fd3346740dfb7f47be9922312b68a4227fada96buzbee} 16491fd3346740dfb7f47be9922312b68a4227fada96buzbee 16503aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler// Allocate a new MIR. 16513aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe BeylerMIR* MIRGraph::NewMIR() { 16523aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler MIR* mir = new (arena_) MIR(); 16533aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler return mir; 16543aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler} 16553aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 1656862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee// Allocate a new basic block. 16572ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromBasicBlock* MIRGraph::NewMemBB(BBType block_type, int block_id) { 1658e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* bb = new (arena_) BasicBlock(block_id, block_type, arena_); 16598512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 1660862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee // TUNING: better estimate of the exit block predecessors? 1661e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bb->predecessors.reserve((block_type == kExitBlock) ? 2048 : 2); 1662862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee block_id_map_.Put(block_id, block_id); 1663862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee return bb; 1664862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee} 16651fd3346740dfb7f47be9922312b68a4227fada96buzbee 16664e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beylervoid MIRGraph::InitializeConstantPropagation() { 16674e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beyler is_constant_v_ = new (arena_) ArenaBitVector(arena_, GetNumSSARegs(), false); 166883cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko constant_values_ = static_cast<int*>(arena_->Alloc(sizeof(int) * GetNumSSARegs(), kArenaAllocDFInfo)); 16694e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beyler} 16704e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beyler 16714e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beylervoid MIRGraph::InitializeMethodUses() { 16728512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // The gate starts by initializing the use counts. 16734e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beyler int num_ssa_regs = GetNumSSARegs(); 1674e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko use_counts_.clear(); 1675e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko use_counts_.reserve(num_ssa_regs + 32); 1676e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko use_counts_.resize(num_ssa_regs, 0u); 1677e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko raw_use_counts_.clear(); 1678e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko raw_use_counts_.reserve(num_ssa_regs + 32); 1679e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko raw_use_counts_.resize(num_ssa_regs, 0u); 16804e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beyler} 16814e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beyler 1682a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Markovoid MIRGraph::SSATransformationStart() { 1683a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko DCHECK(temp_scoped_alloc_.get() == nullptr); 1684a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko temp_scoped_alloc_.reset(ScopedArenaAllocator::Create(&cu_->arena_stack)); 1685f585e549682a98eec12f92033e9634dc162b7df8Vladimir Marko temp_.ssa.num_vregs = GetNumOfCodeAndTempVRs(); 1686f585e549682a98eec12f92033e9634dc162b7df8Vladimir Marko temp_.ssa.work_live_vregs = new (temp_scoped_alloc_.get()) ArenaBitVector( 1687f585e549682a98eec12f92033e9634dc162b7df8Vladimir Marko temp_scoped_alloc_.get(), temp_.ssa.num_vregs, false, kBitMapRegisterV); 16884e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beyler} 16894e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beyler 1690a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Markovoid MIRGraph::SSATransformationEnd() { 1691a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko // Verify the dataflow information after the pass. 1692a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko if (cu_->enable_debug & (1 << kDebugVerifyDataflow)) { 1693a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko VerifyDataflow(); 1694a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko } 1695a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko 1696f585e549682a98eec12f92033e9634dc162b7df8Vladimir Marko temp_.ssa.num_vregs = 0u; 1697f585e549682a98eec12f92033e9634dc162b7df8Vladimir Marko temp_.ssa.work_live_vregs = nullptr; 1698f585e549682a98eec12f92033e9634dc162b7df8Vladimir Marko temp_.ssa.def_block_matrix = nullptr; 1699a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko DCHECK(temp_scoped_alloc_.get() != nullptr); 1700a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko temp_scoped_alloc_.reset(); 1701c029c98cc056bc247b69160f413ee7ce9a93d8c3Johnny Qiu 1702c029c98cc056bc247b69160f413ee7ce9a93d8c3Johnny Qiu // Update the maximum number of reachable blocks. 1703c029c98cc056bc247b69160f413ee7ce9a93d8c3Johnny Qiu max_num_reachable_blocks_ = num_reachable_blocks_; 1704a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko} 1705a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko 1706750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusorusize_t MIRGraph::GetNumDalvikInsns() const { 1707750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru size_t cumulative_size = 0u; 1708750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru bool counted_current_item = false; 1709750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru const uint8_t size_for_null_code_item = 2u; 1710750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru 1711750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru for (auto it : m_units_) { 1712750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru const DexFile::CodeItem* code_item = it->GetCodeItem(); 1713750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru // Even if the code item is null, we still count non-zero value so that 1714750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru // each m_unit is counted as having impact. 1715750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru cumulative_size += (code_item == nullptr ? 1716750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru size_for_null_code_item : code_item->insns_size_in_code_units_); 1717750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru if (code_item == current_code_item_) { 1718750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru counted_current_item = true; 1719750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru } 1720750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru } 1721750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru 1722750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru // If the current code item was not counted yet, count it now. 1723750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru // This can happen for example in unit tests where some fields like m_units_ 1724750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru // are not initialized. 1725750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru if (counted_current_item == false) { 1726750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru cumulative_size += (current_code_item_ == nullptr ? 1727750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru size_for_null_code_item : current_code_item_->insns_size_in_code_units_); 1728750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru } 1729750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru 1730750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru return cumulative_size; 1731750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru} 1732750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru 173355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Markostatic BasicBlock* SelectTopologicalSortOrderFallBack( 173455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko MIRGraph* mir_graph, const ArenaBitVector* current_loop, 173555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko const ScopedArenaVector<size_t>* visited_cnt_values, ScopedArenaAllocator* allocator, 173655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ScopedArenaVector<BasicBlockId>* tmp_stack) { 173755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // No true loop head has been found but there may be true loop heads after the mess we need 173855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // to resolve. To avoid taking one of those, pick the candidate with the highest number of 173955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // reachable unvisited nodes. That candidate will surely be a part of a loop. 174055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko BasicBlock* fall_back = nullptr; 174155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko size_t fall_back_num_reachable = 0u; 174255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Reuse the same bit vector for each candidate to mark reachable unvisited blocks. 174355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ArenaBitVector candidate_reachable(allocator, mir_graph->GetNumBlocks(), false, kBitMapMisc); 174455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko AllNodesIterator iter(mir_graph); 174555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko for (BasicBlock* candidate = iter.Next(); candidate != nullptr; candidate = iter.Next()) { 174655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (candidate->hidden || // Hidden, or 174755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko candidate->visited || // already processed, or 174855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko (*visited_cnt_values)[candidate->id] == 0u || // no processed predecessors, or 174955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko (current_loop != nullptr && // outside current loop. 175055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko !current_loop->IsBitSet(candidate->id))) { 175155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko continue; 175255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 175355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko DCHECK(tmp_stack->empty()); 175455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko tmp_stack->push_back(candidate->id); 175555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko candidate_reachable.ClearAllBits(); 175655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko size_t num_reachable = 0u; 175755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko while (!tmp_stack->empty()) { 175855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko BasicBlockId current_id = tmp_stack->back(); 175955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko tmp_stack->pop_back(); 176055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko BasicBlock* current_bb = mir_graph->GetBasicBlock(current_id); 176155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko DCHECK(current_bb != nullptr); 176255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ChildBlockIterator child_iter(current_bb, mir_graph); 176355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko BasicBlock* child_bb = child_iter.Next(); 176455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko for ( ; child_bb != nullptr; child_bb = child_iter.Next()) { 176555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko DCHECK(!child_bb->hidden); 176655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (child_bb->visited || // Already processed, or 176755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko (current_loop != nullptr && // outside current loop. 176855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko !current_loop->IsBitSet(child_bb->id))) { 176955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko continue; 177055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 177155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (!candidate_reachable.IsBitSet(child_bb->id)) { 177255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko candidate_reachable.SetBit(child_bb->id); 177355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko tmp_stack->push_back(child_bb->id); 177455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko num_reachable += 1u; 177555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 177655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 177755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 177855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (fall_back_num_reachable < num_reachable) { 177955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko fall_back_num_reachable = num_reachable; 178055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko fall_back = candidate; 178155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 178255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 178355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko return fall_back; 178455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko} 178544e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 178655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko// Compute from which unvisited blocks is bb_id reachable through unvisited blocks. 178755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Markostatic void ComputeUnvisitedReachableFrom(MIRGraph* mir_graph, BasicBlockId bb_id, 178855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ArenaBitVector* reachable, 178955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ScopedArenaVector<BasicBlockId>* tmp_stack) { 179055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // NOTE: Loop heads indicated by the "visited" flag. 179155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko DCHECK(tmp_stack->empty()); 179255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko reachable->ClearAllBits(); 179355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko tmp_stack->push_back(bb_id); 179455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko while (!tmp_stack->empty()) { 179555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko BasicBlockId current_id = tmp_stack->back(); 179655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko tmp_stack->pop_back(); 179755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko BasicBlock* current_bb = mir_graph->GetBasicBlock(current_id); 179855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko DCHECK(current_bb != nullptr); 1799e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (BasicBlockId pred_id : current_bb->predecessors) { 1800e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* pred_bb = mir_graph->GetBasicBlock(pred_id); 1801e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko DCHECK(pred_bb != nullptr); 180255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (!pred_bb->visited && !reachable->IsBitSet(pred_bb->id)) { 180355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko reachable->SetBit(pred_bb->id); 180455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko tmp_stack->push_back(pred_bb->id); 180555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 180655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 180744e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler } 180855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko} 180944e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 181055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Markovoid MIRGraph::ComputeTopologicalSortOrder() { 1811622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko ScopedArenaAllocator allocator(&cu_->arena_stack); 181255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko unsigned int num_blocks = GetNumBlocks(); 181355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko 1814622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko ScopedArenaQueue<BasicBlock*> q(allocator.Adapter()); 181555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ScopedArenaVector<size_t> visited_cnt_values(num_blocks, 0u, allocator.Adapter()); 181655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ScopedArenaVector<BasicBlockId> loop_head_stack(allocator.Adapter()); 181755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko size_t max_nested_loops = 0u; 181855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ArenaBitVector loop_exit_blocks(&allocator, num_blocks, false, kBitMapMisc); 181955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_exit_blocks.ClearAllBits(); 1820622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko 182155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Count the number of blocks to process and add the entry block(s). 182255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko unsigned int num_blocks_to_process = 0u; 1823e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (BasicBlock* bb : block_list_) { 182444e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler if (bb->hidden == true) { 182544e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler continue; 182644e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler } 182744e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 182855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko num_blocks_to_process += 1u; 1829622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko 1830e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko if (bb->predecessors.size() == 0u) { 183155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Add entry block to the queue. 183244e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler q.push(bb); 183344e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler } 183444e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler } 183544e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 1836e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko // Clear the topological order arrays. 1837e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_.clear(); 1838e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_.reserve(num_blocks); 1839e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_loop_ends_.clear(); 1840e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_loop_ends_.resize(num_blocks, 0u); 1841e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_indexes_.clear(); 1842e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_indexes_.resize(num_blocks, static_cast<uint16_t>(-1)); 184355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko 184455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Mark all blocks as unvisited. 184555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ClearAllVisitedFlags(); 184655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko 184755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // For loop heads, keep track from which blocks they are reachable not going through other 184855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // loop heads. Other loop heads are excluded to detect the heads of nested loops. The children 184955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // in this set go into the loop body, the other children are jumping over the loop. 185055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ScopedArenaVector<ArenaBitVector*> loop_head_reachable_from(allocator.Adapter()); 185155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_head_reachable_from.resize(num_blocks, nullptr); 185255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Reuse the same temp stack whenever calculating a loop_head_reachable_from[loop_head_id]. 185355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ScopedArenaVector<BasicBlockId> tmp_stack(allocator.Adapter()); 185455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko 185555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko while (num_blocks_to_process != 0u) { 1856622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko BasicBlock* bb = nullptr; 1857622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko if (!q.empty()) { 185855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko num_blocks_to_process -= 1u; 1859622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko // Get top. 1860622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko bb = q.front(); 1861622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko q.pop(); 186255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (bb->visited) { 186355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Loop head: it was already processed, mark end and copy exit blocks to the queue. 186455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko DCHECK(q.empty()) << PrettyMethod(cu_->method_idx, *cu_->dex_file); 1865e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko uint16_t idx = static_cast<uint16_t>(topological_order_.size()); 1866e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_loop_ends_[topological_order_indexes_[bb->id]] = idx; 186755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko DCHECK_EQ(loop_head_stack.back(), bb->id); 186855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_head_stack.pop_back(); 186955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ArenaBitVector* reachable = 187055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_head_stack.empty() ? nullptr : loop_head_reachable_from[loop_head_stack.back()]; 187155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko for (BasicBlockId candidate_id : loop_exit_blocks.Indexes()) { 187255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (reachable == nullptr || reachable->IsBitSet(candidate_id)) { 187355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko q.push(GetBasicBlock(candidate_id)); 187455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // NOTE: The BitVectorSet::IndexIterator will not check the pointed-to bit again, 187555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // so clearing the bit has no effect on the iterator. 187655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_exit_blocks.ClearBit(candidate_id); 187755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 187855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 187955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko continue; 188055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 1881622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko } else { 188255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Find the new loop head. 188355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko AllNodesIterator iter(this); 188455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko while (true) { 188555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko BasicBlock* candidate = iter.Next(); 188655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (candidate == nullptr) { 188755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // We did not find a true loop head, fall back to a reachable block in any loop. 188855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ArenaBitVector* current_loop = 188955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_head_stack.empty() ? nullptr : loop_head_reachable_from[loop_head_stack.back()]; 189055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko bb = SelectTopologicalSortOrderFallBack(this, current_loop, &visited_cnt_values, 189155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko &allocator, &tmp_stack); 189255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko DCHECK(bb != nullptr) << PrettyMethod(cu_->method_idx, *cu_->dex_file); 189355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (kIsDebugBuild && cu_->dex_file != nullptr) { 189455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko LOG(INFO) << "Topological sort order: Using fall-back in " 189555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko << PrettyMethod(cu_->method_idx, *cu_->dex_file) << " BB #" << bb->id 189655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko << " @0x" << std::hex << bb->start_offset 189755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko << ", num_blocks = " << std::dec << num_blocks; 189855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 189955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko break; 190055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 190155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (candidate->hidden || // Hidden, or 190255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko candidate->visited || // already processed, or 190355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko visited_cnt_values[candidate->id] == 0u || // no processed predecessors, or 190455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko (!loop_head_stack.empty() && // outside current loop. 190555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko !loop_head_reachable_from[loop_head_stack.back()]->IsBitSet(candidate->id))) { 1906622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko continue; 1907622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko } 190855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko 1909e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (BasicBlockId pred_id : candidate->predecessors) { 1910e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* pred_bb = GetBasicBlock(pred_id); 1911e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko DCHECK(pred_bb != nullptr); 191255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (pred_bb != candidate && !pred_bb->visited && 191355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko !pred_bb->dominators->IsBitSet(candidate->id)) { 1914e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko candidate = nullptr; // Set candidate to null to indicate failure. 1915e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko break; 1916622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko } 1917622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko } 1918e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko if (candidate != nullptr) { 191955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko bb = candidate; 192055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko break; 192155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 1922622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko } 192355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Compute blocks from which the loop head is reachable and process those blocks first. 192455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ArenaBitVector* reachable = 192555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko new (&allocator) ArenaBitVector(&allocator, num_blocks, false, kBitMapMisc); 192655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_head_reachable_from[bb->id] = reachable; 192755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ComputeUnvisitedReachableFrom(this, bb->id, reachable, &tmp_stack); 192855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Now mark as loop head. (Even if it's only a fall back when we don't find a true loop.) 192955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_head_stack.push_back(bb->id); 193055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko max_nested_loops = std::max(max_nested_loops, loop_head_stack.size()); 1931622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko } 193244e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 193344e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler DCHECK_EQ(bb->hidden, false); 1934622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko DCHECK_EQ(bb->visited, false); 1935622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko bb->visited = true; 193644e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 1937622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko // Now add the basic block. 1938e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko uint16_t idx = static_cast<uint16_t>(topological_order_.size()); 1939e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_indexes_[bb->id] = idx; 1940e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_.push_back(bb->id); 194144e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 194255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Update visited_cnt_values for children. 1943622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko ChildBlockIterator succIter(bb, this); 1944622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko BasicBlock* successor = succIter.Next(); 1945622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko for ( ; successor != nullptr; successor = succIter.Next()) { 194655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (successor->hidden) { 1947622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko continue; 1948622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko } 194944e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 195055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // One more predecessor was visited. 195155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko visited_cnt_values[successor->id] += 1u; 1952e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko if (visited_cnt_values[successor->id] == successor->predecessors.size()) { 195355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (loop_head_stack.empty() || 195455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_head_reachable_from[loop_head_stack.back()]->IsBitSet(successor->id)) { 195555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko q.push(successor); 195655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } else { 195755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko DCHECK(!loop_exit_blocks.IsBitSet(successor->id)); 195855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_exit_blocks.SetBit(successor->id); 195955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 196044e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler } 196144e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler } 196244e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler } 196355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko 196455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Prepare the loop head stack for iteration. 1965e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_loop_head_stack_.clear(); 1966e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_loop_head_stack_.reserve(max_nested_loops); 1967415ac88a6471792a28cf2b457fe4ba9dc099396eVladimir Marko max_nested_loops_ = max_nested_loops; 196844e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler} 196944e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 197044e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beylerbool BasicBlock::IsExceptionBlock() const { 197144e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler if (block_type == kExceptionHandling) { 197244e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler return true; 197344e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler } 197444e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler return false; 197544e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler} 197644e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 197704f4d8abe45d6e79eca983e057de76aea24b7df9Wei Jinbool MIRGraph::HasSuspendTestBetween(BasicBlock* source, BasicBlockId target_id) { 197804f4d8abe45d6e79eca983e057de76aea24b7df9Wei Jin BasicBlock* target = GetBasicBlock(target_id); 197904f4d8abe45d6e79eca983e057de76aea24b7df9Wei Jin 198004f4d8abe45d6e79eca983e057de76aea24b7df9Wei Jin if (source == nullptr || target == nullptr) 198104f4d8abe45d6e79eca983e057de76aea24b7df9Wei Jin return false; 198204f4d8abe45d6e79eca983e057de76aea24b7df9Wei Jin 198304f4d8abe45d6e79eca983e057de76aea24b7df9Wei Jin int idx; 1984e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (idx = gen_suspend_test_list_.size() - 1; idx >= 0; idx--) { 1985e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* bb = gen_suspend_test_list_[idx]; 198604f4d8abe45d6e79eca983e057de76aea24b7df9Wei Jin if (bb == source) 198704f4d8abe45d6e79eca983e057de76aea24b7df9Wei Jin return true; // The block has been inserted by a suspend check before. 198804f4d8abe45d6e79eca983e057de76aea24b7df9Wei Jin if (source->dominators->IsBitSet(bb->id) && bb->dominators->IsBitSet(target_id)) 198904f4d8abe45d6e79eca983e057de76aea24b7df9Wei Jin return true; 199004f4d8abe45d6e79eca983e057de76aea24b7df9Wei Jin } 199104f4d8abe45d6e79eca983e057de76aea24b7df9Wei Jin 199204f4d8abe45d6e79eca983e057de76aea24b7df9Wei Jin return false; 199304f4d8abe45d6e79eca983e057de76aea24b7df9Wei Jin} 199404f4d8abe45d6e79eca983e057de76aea24b7df9Wei Jin 1995f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe BeylerChildBlockIterator::ChildBlockIterator(BasicBlock* bb, MIRGraph* mir_graph) 1996f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler : basic_block_(bb), mir_graph_(mir_graph), visited_fallthrough_(false), 1997f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler visited_taken_(false), have_successors_(false) { 1998f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler // Check if we actually do have successors. 1999f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler if (basic_block_ != 0 && basic_block_->successor_block_list_type != kNotUsed) { 2000f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler have_successors_ = true; 2001e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko successor_iter_ = basic_block_->successor_blocks.cbegin(); 2002f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler } 2003f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler} 2004f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler 2005f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe BeylerBasicBlock* ChildBlockIterator::Next() { 2006f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler // We check if we have a basic block. If we don't we cannot get next child. 2007f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler if (basic_block_ == nullptr) { 2008f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler return nullptr; 2009f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler } 2010f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler 2011f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler // If we haven't visited fallthrough, return that. 2012f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler if (visited_fallthrough_ == false) { 2013f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler visited_fallthrough_ = true; 2014f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler 2015f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler BasicBlock* result = mir_graph_->GetBasicBlock(basic_block_->fall_through); 2016f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler if (result != nullptr) { 2017f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler return result; 2018f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler } 2019f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler } 2020f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler 2021f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler // If we haven't visited taken, return that. 2022f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler if (visited_taken_ == false) { 2023f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler visited_taken_ = true; 2024f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler 2025f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler BasicBlock* result = mir_graph_->GetBasicBlock(basic_block_->taken); 2026f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler if (result != nullptr) { 2027f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler return result; 2028f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler } 2029f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler } 2030f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler 2031f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler // We visited both taken and fallthrough. Now check if we have successors we need to visit. 2032f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler if (have_successors_ == true) { 2033f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler // Get information about next successor block. 2034e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko auto end = basic_block_->successor_blocks.cend(); 2035e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko while (successor_iter_ != end) { 2036e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko SuccessorBlockInfo* successor_block_info = *successor_iter_; 2037e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko ++successor_iter_; 2038989367a47b015dd85f850cf756b436fb044b5aeaNiranjan Kumar // If block was replaced by zero block, take next one. 2039989367a47b015dd85f850cf756b436fb044b5aeaNiranjan Kumar if (successor_block_info->block != NullBasicBlockId) { 2040989367a47b015dd85f850cf756b436fb044b5aeaNiranjan Kumar return mir_graph_->GetBasicBlock(successor_block_info->block); 2041989367a47b015dd85f850cf756b436fb044b5aeaNiranjan Kumar } 2042f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler } 2043f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler } 2044f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler 2045f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler // We do not have anything. 2046f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler return nullptr; 2047f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler} 2048f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler 20498512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe BeylerBasicBlock* BasicBlock::Copy(CompilationUnit* c_unit) { 20508512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler MIRGraph* mir_graph = c_unit->mir_graph.get(); 20518512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return Copy(mir_graph); 20528512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 20533aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 20548512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe BeylerBasicBlock* BasicBlock::Copy(MIRGraph* mir_graph) { 20558512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler BasicBlock* result_bb = mir_graph->CreateNewBB(block_type); 20563aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 20578512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // We don't do a memcpy style copy here because it would lead to a lot of things 20588512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // to clean up. Let us do it by hand instead. 20598512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Copy in taken and fallthrough. 20608512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler result_bb->fall_through = fall_through; 20618512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler result_bb->taken = taken; 20623aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 20638512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Copy successor links if needed. 20648512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler ArenaAllocator* arena = mir_graph->GetArena(); 20653aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 20668512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler result_bb->successor_block_list_type = successor_block_list_type; 20678512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (result_bb->successor_block_list_type != kNotUsed) { 2068e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko result_bb->successor_blocks.reserve(successor_blocks.size()); 2069e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (SuccessorBlockInfo* sbi_old : successor_blocks) { 2070e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko SuccessorBlockInfo* sbi_new = static_cast<SuccessorBlockInfo*>( 2071e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko arena->Alloc(sizeof(SuccessorBlockInfo), kArenaAllocSuccessor)); 20728512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler memcpy(sbi_new, sbi_old, sizeof(SuccessorBlockInfo)); 2073e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko result_bb->successor_blocks.push_back(sbi_new); 20743aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler } 20758512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 20763aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 20778512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Copy offset, method. 20788512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler result_bb->start_offset = start_offset; 20793aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 20808512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Now copy instructions. 20818512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler for (MIR* mir = first_mir_insn; mir != 0; mir = mir->next) { 20828512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Get a copy first. 20838512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler MIR* copy = mir->Copy(mir_graph); 20843aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 20858512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Append it. 20868512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler result_bb->AppendMIR(copy); 20873aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler } 20883aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 20898512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return result_bb; 20903aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler} 20913aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 20923aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe BeylerMIR* MIR::Copy(MIRGraph* mir_graph) { 20933aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler MIR* res = mir_graph->NewMIR(); 20943aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler *res = *this; 20953aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 20963aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler // Remove links 20973aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler res->next = nullptr; 20983aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler res->bb = NullBasicBlockId; 20993aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler res->ssa_rep = nullptr; 21003aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 21013aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler return res; 21023aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler} 21033aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 21043aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe BeylerMIR* MIR::Copy(CompilationUnit* c_unit) { 21053aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler return Copy(c_unit->mir_graph.get()); 21063aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler} 21073aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 21083aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyleruint32_t SSARepresentation::GetStartUseIndex(Instruction::Code opcode) { 21093aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler // Default result. 21103aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler int res = 0; 21113aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 21123aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler // We are basically setting the iputs to their igets counterparts. 21133aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler switch (opcode) { 21143aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT: 21153aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT_OBJECT: 21163aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT_BOOLEAN: 21173aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT_BYTE: 21183aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT_CHAR: 21193aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT_SHORT: 21203aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT_QUICK: 21213aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT_OBJECT_QUICK: 212237f05ef45e0393de812d51261dc293240c17294dFred Shih case Instruction::IPUT_BOOLEAN_QUICK: 212337f05ef45e0393de812d51261dc293240c17294dFred Shih case Instruction::IPUT_BYTE_QUICK: 212437f05ef45e0393de812d51261dc293240c17294dFred Shih case Instruction::IPUT_CHAR_QUICK: 212537f05ef45e0393de812d51261dc293240c17294dFred Shih case Instruction::IPUT_SHORT_QUICK: 21263aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::APUT: 21273aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::APUT_OBJECT: 21283aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::APUT_BOOLEAN: 21293aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::APUT_BYTE: 21303aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::APUT_CHAR: 21313aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::APUT_SHORT: 21323aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::SPUT: 21333aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::SPUT_OBJECT: 21343aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::SPUT_BOOLEAN: 21353aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::SPUT_BYTE: 21363aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::SPUT_CHAR: 21373aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::SPUT_SHORT: 21383aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler // Skip the VR containing what to store. 21393aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler res = 1; 21403aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler break; 21413aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT_WIDE: 21423aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT_WIDE_QUICK: 21433aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::APUT_WIDE: 21443aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::SPUT_WIDE: 21453aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler // Skip the two VRs containing what to store. 21463aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler res = 2; 21473aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler break; 21483aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler default: 21493aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler // Do nothing in the general case. 21503aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler break; 21513aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler } 21523aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 21533aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler return res; 21543aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler} 21553aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 2156c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler/** 2157c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler * @brief Given a decoded instruction, it checks whether the instruction 2158c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler * sets a constant and if it does, more information is provided about the 2159c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler * constant being set. 2160c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler * @param ptr_value pointer to a 64-bit holder for the constant. 2161c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler * @param wide Updated by function whether a wide constant is being set by bytecode. 2162c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler * @return Returns false if the decoded instruction does not represent a constant bytecode. 2163c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler */ 2164c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beylerbool MIR::DecodedInstruction::GetConstant(int64_t* ptr_value, bool* wide) const { 2165c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler bool sets_const = true; 2166c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler int64_t value = vB; 2167c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler 2168c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler DCHECK(ptr_value != nullptr); 2169c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler DCHECK(wide != nullptr); 2170c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler 2171c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler switch (opcode) { 2172c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler case Instruction::CONST_4: 2173c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler case Instruction::CONST_16: 2174c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler case Instruction::CONST: 2175c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler *wide = false; 2176c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler value <<= 32; // In order to get the sign extend. 2177c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler value >>= 32; 2178c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler break; 2179c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler case Instruction::CONST_HIGH16: 2180c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler *wide = false; 2181c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler value <<= 48; // In order to get the sign extend. 2182c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler value >>= 32; 2183c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler break; 2184c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler case Instruction::CONST_WIDE_16: 2185c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler case Instruction::CONST_WIDE_32: 2186c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler *wide = true; 2187c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler value <<= 32; // In order to get the sign extend. 2188c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler value >>= 32; 2189c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler break; 2190c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler case Instruction::CONST_WIDE: 2191c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler *wide = true; 2192c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler value = vB_wide; 2193c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler break; 2194c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler case Instruction::CONST_WIDE_HIGH16: 2195c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler *wide = true; 2196c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler value <<= 48; // In order to get the sign extend. 2197c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler break; 2198c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler default: 2199c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler sets_const = false; 2200c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler break; 2201c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler } 2202c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler 2203c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler if (sets_const) { 2204c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler *ptr_value = value; 2205c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler } 2206c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler 2207c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler return sets_const; 2208c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler} 22098512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 22108512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylervoid BasicBlock::ResetOptimizationFlags(uint16_t reset_flags) { 22118512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Reset flags for all MIRs in bb. 22128512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler for (MIR* mir = first_mir_insn; mir != NULL; mir = mir->next) { 22138512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler mir->optimization_flags &= (~reset_flags); 22148512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 22158512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 22168512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 2217312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Markovoid BasicBlock::Hide(MIRGraph* mir_graph) { 22188512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // First lets make it a dalvik bytecode block so it doesn't have any special meaning. 22198512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler block_type = kDalvikByteCode; 22208512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 22218512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Mark it as hidden. 22228512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler hidden = true; 22238512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 22248512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Detach it from its MIRs so we don't generate code for them. Also detached MIRs 22258512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // are updated to know that they no longer have a parent. 22268512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler for (MIR* mir = first_mir_insn; mir != nullptr; mir = mir->next) { 22278512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler mir->bb = NullBasicBlockId; 22288512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 22298512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler first_mir_insn = nullptr; 22308512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_mir_insn = nullptr; 22318512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 2232e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (BasicBlockId pred_id : predecessors) { 2233e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* pred_bb = mir_graph->GetBasicBlock(pred_id); 2234e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko DCHECK(pred_bb != nullptr); 22358512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 22368512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Sadly we have to go through the children by hand here. 22378512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler pred_bb->ReplaceChild(id, NullBasicBlockId); 22388512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 22398512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 22408512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Iterate through children of bb we are hiding. 22418512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler ChildBlockIterator successorChildIter(this, mir_graph); 22428512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 22438512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler for (BasicBlock* childPtr = successorChildIter.Next(); childPtr != 0; childPtr = successorChildIter.Next()) { 2244e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko // Erase this predecessor from child. 2245e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko childPtr->ErasePredecessor(id); 22468512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 2247f588b50986fe34cba26fc3ff3100af384c081dbaJean Christophe Beyler 2248f588b50986fe34cba26fc3ff3100af384c081dbaJean Christophe Beyler // Remove link to children. 2249f588b50986fe34cba26fc3ff3100af384c081dbaJean Christophe Beyler taken = NullBasicBlockId; 2250f588b50986fe34cba26fc3ff3100af384c081dbaJean Christophe Beyler fall_through = NullBasicBlockId; 2251f588b50986fe34cba26fc3ff3100af384c081dbaJean Christophe Beyler successor_block_list_type = kNotUsed; 22528512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 22538512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 2254312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko/* 2255312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko * Kill an unreachable block and all blocks that become unreachable by killing this one. 2256312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko */ 2257312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Markovoid BasicBlock::KillUnreachable(MIRGraph* mir_graph) { 2258312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko DCHECK(predecessors.empty()); // Unreachable. 2259312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko 2260312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko // Mark as dead and hidden. 2261312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko block_type = kDead; 2262312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko hidden = true; 2263312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko 2264312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko // Detach it from its MIRs so we don't generate code for them. Also detached MIRs 2265312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko // are updated to know that they no longer have a parent. 2266312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko for (MIR* mir = first_mir_insn; mir != nullptr; mir = mir->next) { 2267312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko mir->bb = NullBasicBlockId; 2268312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko } 2269312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko first_mir_insn = nullptr; 2270312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko last_mir_insn = nullptr; 2271312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko 2272312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko data_flow_info = nullptr; 2273312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko 2274312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko // Erase this bb from all children's predecessors and kill unreachable children. 2275312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko ChildBlockIterator iter(this, mir_graph); 2276312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko for (BasicBlock* succ_bb = iter.Next(); succ_bb != nullptr; succ_bb = iter.Next()) { 2277312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko succ_bb->ErasePredecessor(id); 2278312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko if (succ_bb->predecessors.empty()) { 2279312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko succ_bb->KillUnreachable(mir_graph); 2280312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko } 2281312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko } 2282312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko 2283312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko // Remove links to children. 2284312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko fall_through = NullBasicBlockId; 2285312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko taken = NullBasicBlockId; 2286312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko successor_block_list_type = kNotUsed; 2287312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko 2288312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko if (kIsDebugBuild) { 2289312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko if (catch_entry) { 2290312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko DCHECK_EQ(mir_graph->catches_.count(start_offset), 1u); 2291312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko mir_graph->catches_.erase(start_offset); 2292312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko } 2293312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko } 2294312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko} 2295312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko 22968512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylerbool BasicBlock::IsSSALiveOut(const CompilationUnit* c_unit, int ssa_reg) { 22978512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // In order to determine if the ssa reg is live out, we scan all the MIRs. We remember 22988512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // the last SSA number of the same dalvik register. At the end, if it is different than ssa_reg, 22998512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // then it is not live out of this BB. 23008512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler int dalvik_reg = c_unit->mir_graph->SRegToVReg(ssa_reg); 23018512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23028512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler int last_ssa_reg = -1; 23038512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23048512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Walk through the MIRs backwards. 23058512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler for (MIR* mir = first_mir_insn; mir != nullptr; mir = mir->next) { 23068512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Get ssa rep. 23078512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler SSARepresentation *ssa_rep = mir->ssa_rep; 23088512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23098512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Go through the defines for this MIR. 23108512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler for (int i = 0; i < ssa_rep->num_defs; i++) { 23118512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler DCHECK(ssa_rep->defs != nullptr); 23128512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23138512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Get the ssa reg. 23148512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler int def_ssa_reg = ssa_rep->defs[i]; 23158512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23168512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Get dalvik reg. 23178512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler int def_dalvik_reg = c_unit->mir_graph->SRegToVReg(def_ssa_reg); 23188512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23198512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Compare dalvik regs. 23208512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (dalvik_reg == def_dalvik_reg) { 23218512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // We found a def of the register that we are being asked about. 23228512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Remember it. 23238512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_ssa_reg = def_ssa_reg; 23248512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 23258512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 23268512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 23278512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23288512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (last_ssa_reg == -1) { 23298512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // If we get to this point we couldn't find a define of register user asked about. 23308512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Let's assume the user knows what he's doing so we can be safe and say that if we 23318512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // couldn't find a def, it is live out. 23328512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return true; 23338512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 23348512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23358512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // If it is not -1, we found a match, is it ssa_reg? 23368512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return (ssa_reg == last_ssa_reg); 23378512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 23388512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23398512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylerbool BasicBlock::ReplaceChild(BasicBlockId old_bb, BasicBlockId new_bb) { 23408512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // We need to check taken, fall_through, and successor_blocks to replace. 23418512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler bool found = false; 23428512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (taken == old_bb) { 23438512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler taken = new_bb; 23448512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler found = true; 23458512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 23468512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23478512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (fall_through == old_bb) { 23488512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler fall_through = new_bb; 23498512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler found = true; 23508512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 23518512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23528512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (successor_block_list_type != kNotUsed) { 2353e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (SuccessorBlockInfo* successor_block_info : successor_blocks) { 23548512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (successor_block_info->block == old_bb) { 23558512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler successor_block_info->block = new_bb; 23568512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler found = true; 23578512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 23588512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 23598512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 23608512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23618512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return found; 23628512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 23638512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 2364e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Markovoid BasicBlock::ErasePredecessor(BasicBlockId old_pred) { 2365e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko auto pos = std::find(predecessors.begin(), predecessors.end(), old_pred); 2366e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko DCHECK(pos != predecessors.end()); 2367312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko // It's faster to move the back() to *pos than erase(pos). 2368312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko *pos = predecessors.back(); 2369312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko predecessors.pop_back(); 2370312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko size_t idx = std::distance(predecessors.begin(), pos); 2371312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko for (MIR* mir = first_mir_insn; mir != nullptr; mir = mir->next) { 2372312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko if (static_cast<int>(mir->dalvikInsn.opcode) != kMirOpPhi) { 2373312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko break; 2374312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko } 2375312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko DCHECK_EQ(mir->ssa_rep->num_uses - 1u, predecessors.size()); 2376312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko DCHECK_EQ(mir->meta.phi_incoming[idx], old_pred); 2377312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko mir->meta.phi_incoming[idx] = mir->meta.phi_incoming[predecessors.size()]; 2378312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko mir->ssa_rep->uses[idx] = mir->ssa_rep->uses[predecessors.size()]; 2379312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko mir->ssa_rep->num_uses = predecessors.size(); 2380312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko } 2381e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko} 23828512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 2383e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Markovoid BasicBlock::UpdatePredecessor(BasicBlockId old_pred, BasicBlockId new_pred) { 2384e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko DCHECK_NE(new_pred, NullBasicBlockId); 2385e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko auto pos = std::find(predecessors.begin(), predecessors.end(), old_pred); 2386312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko DCHECK(pos != predecessors.end()); 2387312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko *pos = new_pred; 2388312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko size_t idx = std::distance(predecessors.begin(), pos); 2389312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko for (MIR* mir = first_mir_insn; mir != nullptr; mir = mir->next) { 2390312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko if (static_cast<int>(mir->dalvikInsn.opcode) != kMirOpPhi) { 2391312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko break; 2392312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko } 2393312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko DCHECK_EQ(mir->meta.phi_incoming[idx], old_pred); 2394312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko mir->meta.phi_incoming[idx] = new_pred; 23958512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 23968512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 23978512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23988512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler// Create a new basic block with block_id as num_blocks_ that is 23998512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler// post-incremented. 24008512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe BeylerBasicBlock* MIRGraph::CreateNewBB(BBType block_type) { 24018512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler BasicBlock* res = NewMemBB(block_type, num_blocks_++); 2402e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko block_list_.push_back(res); 24038512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return res; 24048512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 24058512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 24062469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beylervoid MIRGraph::CalculateBasicBlockInformation() { 24072469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler PassDriverMEPostOpt driver(cu_); 24082469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler driver.Launch(); 24092469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler} 24102469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler 24112469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beylervoid MIRGraph::InitializeBasicBlockData() { 2412e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko num_blocks_ = block_list_.size(); 24132469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler} 24142469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler 2415fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beylerint MIR::DecodedInstruction::FlagsOf() const { 2416fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler // Calculate new index. 2417fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler int idx = static_cast<int>(opcode) - kNumPackedOpcodes; 2418fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler 2419fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler // Check if it is an extended or not. 2420fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler if (idx < 0) { 2421fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::FlagsOf(opcode); 2422fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler } 2423fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler 2424fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler // For extended, we use a switch. 2425fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler switch (static_cast<int>(opcode)) { 2426fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPhi: 2427fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2428fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpCopy: 2429fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2430fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpFusedCmplFloat: 2431fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue | Instruction::kBranch; 2432fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpFusedCmpgFloat: 2433fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue | Instruction::kBranch; 2434fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpFusedCmplDouble: 2435fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue | Instruction::kBranch; 2436fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpFusedCmpgDouble: 2437fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue | Instruction::kBranch; 2438fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpFusedCmpLong: 2439fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue | Instruction::kBranch; 2440fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpNop: 2441fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2442fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpNullCheck: 2443fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue | Instruction::kThrow; 2444fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpRangeCheck: 2445fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue | Instruction::kThrow; 2446fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpDivZeroCheck: 2447fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue | Instruction::kThrow; 2448fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpCheck: 2449b7fc629dc562ee9f3df04a112a70b7868664f94dUdayan Banerji return Instruction::kContinue | Instruction::kThrow; 2450fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpCheckPart2: 2451b7fc629dc562ee9f3df04a112a70b7868664f94dUdayan Banerji return Instruction::kContinue; 2452fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpSelect: 2453fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2454fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpConstVector: 2455fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2456fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpMoveVector: 2457fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2458fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedMultiply: 2459fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2460fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedAddition: 2461fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2462fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedSubtract: 2463fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2464fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedShiftLeft: 2465fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2466fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedSignedShiftRight: 2467fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2468fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedUnsignedShiftRight: 2469fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2470fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedAnd: 2471fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2472fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedOr: 2473fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2474fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedXor: 2475fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2476fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedAddReduce: 2477fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2478fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedReduce: 2479fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2480fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedSet: 2481fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2482fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpReserveVectorRegisters: 2483fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2484fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpReturnVectorRegisters: 2485fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2486b7fc629dc562ee9f3df04a112a70b7868664f94dUdayan Banerji case kMirOpMemBarrier: 2487b7fc629dc562ee9f3df04a112a70b7868664f94dUdayan Banerji return Instruction::kContinue; 2488b7fc629dc562ee9f3df04a112a70b7868664f94dUdayan Banerji case kMirOpPackedArrayGet: 2489b7fc629dc562ee9f3df04a112a70b7868664f94dUdayan Banerji return Instruction::kContinue | Instruction::kThrow; 2490b7fc629dc562ee9f3df04a112a70b7868664f94dUdayan Banerji case kMirOpPackedArrayPut: 2491b7fc629dc562ee9f3df04a112a70b7868664f94dUdayan Banerji return Instruction::kContinue | Instruction::kThrow; 2492fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler default: 2493fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler LOG(WARNING) << "ExtendedFlagsOf: Unhandled case: " << static_cast<int> (opcode); 2494fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return 0; 2495fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler } 2496fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler} 24977934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom} // namespace art 2498