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> 21cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe#include <unistd.h> 22f3e2cc4a38389aa75eb8ee3973a535254bf1c8d2Nicolas Geoffray 23e77493c7217efdd1a0ecef521a6845a13da0305bIan Rogers#include "base/bit_vector-inl.h" 240b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe#include "base/logging.h" 256282dc12440a2072dc06a616160027ff21bd895eIan Rogers#include "base/stl_util.h" 260b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe#include "base/stringprintf.h" 27b666f4805c8ae707ea6fd7f6c7f375e0b000dba8Mathieu Chartier#include "base/scoped_arena_containers.h" 280b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe#include "compiler_ir.h" 29311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#include "dex_file-inl.h" 300b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe#include "dex_flags.h" 3129a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers#include "dex_instruction-inl.h" 320b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe#include "driver/compiler_driver.h" 330b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe#include "driver/dex_compilation_unit.h" 345bdab12d8b48ca4c395d9d2c506ebff0df01b734Mathieu Chartier#include "dex/quick/quick_compiler.h" 35f3e2cc4a38389aa75eb8ee3973a535254bf1c8d2Nicolas Geoffray#include "leb128.h" 362469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler#include "pass_driver_me_post_opt.h" 3753c913bb71b218714823c8c87a1f92830c336f61Andreas Gampe#include "stack.h" 3841b175aba41c9365a1c53b8a1afbd17129c87c14Vladimir Marko#include "utils.h" 395816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko 40311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeenamespace art { 41311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 42311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define MAX_PATTERN_LEN 5 43311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 441fd3346740dfb7f47be9922312b68a4227fada96buzbeeconst char* MIRGraph::extended_mir_op_names_[kMirOpLast - kMirOpFirst] = { 451fd3346740dfb7f47be9922312b68a4227fada96buzbee "Phi", 461fd3346740dfb7f47be9922312b68a4227fada96buzbee "Copy", 471fd3346740dfb7f47be9922312b68a4227fada96buzbee "FusedCmplFloat", 481fd3346740dfb7f47be9922312b68a4227fada96buzbee "FusedCmpgFloat", 491fd3346740dfb7f47be9922312b68a4227fada96buzbee "FusedCmplDouble", 501fd3346740dfb7f47be9922312b68a4227fada96buzbee "FusedCmpgDouble", 511fd3346740dfb7f47be9922312b68a4227fada96buzbee "FusedCmpLong", 521fd3346740dfb7f47be9922312b68a4227fada96buzbee "Nop", 531fd3346740dfb7f47be9922312b68a4227fada96buzbee "OpNullCheck", 541fd3346740dfb7f47be9922312b68a4227fada96buzbee "OpRangeCheck", 551fd3346740dfb7f47be9922312b68a4227fada96buzbee "OpDivZeroCheck", 56f80552b7e5f627a5dd07af017b7d65dec010ca48Vladimir Marko "Check", 571fd3346740dfb7f47be9922312b68a4227fada96buzbee "Select", 58d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell "ConstVector", 59d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell "MoveVector", 60d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell "PackedMultiply", 61d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell "PackedAddition", 62d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell "PackedSubtract", 63d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell "PackedShiftLeft", 64d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell "PackedSignedShiftRight", 65d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell "PackedUnsignedShiftRight", 66d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell "PackedAnd", 67d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell "PackedOr", 68d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell "PackedXor", 69d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell "PackedAddReduce", 70d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell "PackedReduce", 71d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell "PackedSet", 7260bfe7b3e8f00f0a8ef3f5d8716adfdf86b71f43Udayan Banerji "ReserveVectorRegisters", 7360bfe7b3e8f00f0a8ef3f5d8716adfdf86b71f43Udayan Banerji "ReturnVectorRegisters", 74b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler "MemBarrier", 75b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A "PackedArrayGet", 76b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A "PackedArrayPut", 77a262f7707330dccfb50af6345813083182b61043Ningsheng Jian "MaddInt", 78a262f7707330dccfb50af6345813083182b61043Ningsheng Jian "MsubInt", 79a262f7707330dccfb50af6345813083182b61043Ningsheng Jian "MaddLong", 80a262f7707330dccfb50af6345813083182b61043Ningsheng Jian "MsubLong", 811fd3346740dfb7f47be9922312b68a4227fada96buzbee}; 821fd3346740dfb7f47be9922312b68a4227fada96buzbee 83862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbeeMIRGraph::MIRGraph(CompilationUnit* cu, ArenaAllocator* arena) 842cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier : reg_location_(nullptr), 858081d2b8d7a743729557051d0294e040e61c747aVladimir Marko block_id_map_(std::less<unsigned int>(), arena->Adapter()), 861fd3346740dfb7f47be9922312b68a4227fada96buzbee cu_(cu), 87e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko ssa_base_vregs_(arena->Adapter(kArenaAllocSSAToDalvikMap)), 88e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko ssa_subscripts_(arena->Adapter(kArenaAllocSSAToDalvikMap)), 892cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier vreg_to_ssa_map_(nullptr), 902cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier ssa_last_defs_(nullptr), 912cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier is_constant_v_(nullptr), 922cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier constant_values_(nullptr), 93e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko use_counts_(arena->Adapter()), 94e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko raw_use_counts_(arena->Adapter()), 95311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee num_reachable_blocks_(0), 964896d7b6fb75add25f2d6ba84346ac83d8ba9d51Jean Christophe Beyler max_num_reachable_blocks_(0), 97312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko dfs_orders_up_to_date_(false), 98ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko domination_up_to_date_(false), 99ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko mir_ssa_rep_up_to_date_(false), 100ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko topological_order_up_to_date_(false), 101e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko dfs_order_(arena->Adapter(kArenaAllocDfsPreOrder)), 102e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko dfs_post_order_(arena->Adapter(kArenaAllocDfsPostOrder)), 103e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko dom_post_order_traversal_(arena->Adapter(kArenaAllocDomPostOrder)), 104e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_(arena->Adapter(kArenaAllocTopologicalSortOrder)), 105e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_loop_ends_(arena->Adapter(kArenaAllocTopologicalSortOrder)), 106e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_indexes_(arena->Adapter(kArenaAllocTopologicalSortOrder)), 107e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_loop_head_stack_(arena->Adapter(kArenaAllocTopologicalSortOrder)), 108415ac88a6471792a28cf2b457fe4ba9dc099396eVladimir Marko max_nested_loops_(0u), 1092cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier i_dom_list_(nullptr), 110bfea9c29e809e04bde4a46591fea64c5a7b922fbVladimir Marko temp_scoped_alloc_(), 111e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko block_list_(arena->Adapter(kArenaAllocBBList)), 1122cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier try_block_addr_(nullptr), 1132cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier entry_block_(nullptr), 1142cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier exit_block_(nullptr), 1152cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier current_code_item_(nullptr), 1168081d2b8d7a743729557051d0294e040e61c747aVladimir Marko m_units_(arena->Adapter()), 1178081d2b8d7a743729557051d0294e040e61c747aVladimir Marko method_stack_(arena->Adapter()), 118311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee current_method_(kInvalidEntry), 119311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee current_offset_(kInvalidEntry), 120311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee def_count_(0), 1212cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier opcode_count_(nullptr), 1221fd3346740dfb7f47be9922312b68a4227fada96buzbee num_ssa_regs_(0), 1238081d2b8d7a743729557051d0294e040e61c747aVladimir Marko extended_basic_blocks_(arena->Adapter()), 1241fd3346740dfb7f47be9922312b68a4227fada96buzbee method_sreg_(0), 125862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee attributes_(METHOD_IS_LEAF), // Start with leaf assumption, change on encountering invoke. 1262cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier checkstats_(nullptr), 127b48819db07f9a0992a72173380c24249d7fc648abuzbee arena_(arena), 128b48819db07f9a0992a72173380c24249d7fc648abuzbee backward_branches_(0), 129da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru forward_branches_(0), 130da7a69b3fa7bb22d087567364b7eb5a75824efd8Razvan A Lupusoru num_non_special_compiler_temps_(0), 1318d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru max_available_special_compiler_temps_(1), // We only need the method ptr as a special temp for now. 1328d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru requested_backend_temp_(false), 1338d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru compiler_temps_committed_(false), 134be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko punt_to_interpreter_(false), 1353d73ba2ce682edfaf41f29521bd6039c6499a1c5Vladimir Marko merged_df_flags_(0u), 136e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko ifield_lowering_infos_(arena->Adapter(kArenaAllocLoweringInfo)), 137e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko sfield_lowering_infos_(arena->Adapter(kArenaAllocLoweringInfo)), 138e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko method_lowering_infos_(arena->Adapter(kArenaAllocLoweringInfo)), 1398b858e16563ebf8e522df026a6ab409f1bd9b3deVladimir Marko suspend_checks_in_loops_(nullptr) { 140f585e549682a98eec12f92033e9634dc162b7df8Vladimir Marko memset(&temp_, 0, sizeof(temp_)); 141e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko use_counts_.reserve(256); 142e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko raw_use_counts_.reserve(256); 143e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko block_list_.reserve(100); 144862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee try_block_addr_ = new (arena_) ArenaBitVector(arena_, 0, true /* expandable */); 1458d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru 1468d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru 1478d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru if (cu_->instruction_set == kX86 || cu_->instruction_set == kX86_64) { 1488d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru // X86 requires a temp to keep track of the method address. 1498d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru // TODO For x86_64, addressing can be done with RIP. When that is implemented, 1508d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru // this needs to be updated to reserve 0 temps for BE. 1518d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru max_available_non_special_compiler_temps_ = cu_->target64 ? 2 : 1; 1528d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru reserved_temps_for_backend_ = max_available_non_special_compiler_temps_; 1538d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru } else { 1548d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru // Other architectures do not have a known lower bound for non-special temps. 1558d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru // We allow the update of the max to happen at BE initialization stage and simply set 0 for now. 1568d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru max_available_non_special_compiler_temps_ = 0; 1578d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru reserved_temps_for_backend_ = 0; 1588d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru } 159311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 160311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 1616282dc12440a2072dc06a616160027ff21bd895eIan RogersMIRGraph::~MIRGraph() { 162e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko STLDeleteElements(&block_list_); 1636282dc12440a2072dc06a616160027ff21bd895eIan Rogers STLDeleteElements(&m_units_); 1646282dc12440a2072dc06a616160027ff21bd895eIan Rogers} 1656282dc12440a2072dc06a616160027ff21bd895eIan Rogers 166311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/* 167311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Parse an instruction, return the length of the instruction 168311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 16929a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogersint MIRGraph::ParseInsn(const uint16_t* code_ptr, MIR::DecodedInstruction* decoded_instruction) { 17029a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers const Instruction* inst = Instruction::At(code_ptr); 17129a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers decoded_instruction->opcode = inst->Opcode(); 17229a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers decoded_instruction->vA = inst->HasVRegA() ? inst->VRegA() : 0; 17329a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers decoded_instruction->vB = inst->HasVRegB() ? inst->VRegB() : 0; 17429a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers decoded_instruction->vB_wide = inst->HasWideVRegB() ? inst->WideVRegB() : 0; 17529a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers decoded_instruction->vC = inst->HasVRegC() ? inst->VRegC() : 0; 17629a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers if (inst->HasVarArgs()) { 17729a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers inst->GetVarArgs(decoded_instruction->arg); 17829a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers } 17929a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers return inst->SizeInCodeUnits(); 180311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 181311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 182311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 183311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/* Split an existing block from the specified code offset into two */ 1840d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeBasicBlock* MIRGraph::SplitBlock(DexOffset code_offset, 1852ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom BasicBlock* orig_block, BasicBlock** immed_pred_block_p) { 1860d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DCHECK_GT(code_offset, orig_block->start_offset); 187311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee MIR* insn = orig_block->first_mir_insn; 1882cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier MIR* prev = nullptr; // Will be set to instruction before split. 189311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee while (insn) { 190311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (insn->offset == code_offset) break; 1910d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee prev = insn; 192311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee insn = insn->next; 193311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 1942cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (insn == nullptr) { 195311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee LOG(FATAL) << "Break split failed"; 196311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 19733c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski // Now insn is at the instruction where we want to split, namely 19833c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski // insn will be the first instruction of the "bottom" block. 19933c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski // Similarly, prev will be the last instruction of the "top" block 20033c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski 201e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* bottom_block = CreateNewBB(kDalvikByteCode); 202311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 203311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bottom_block->start_offset = code_offset; 204311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bottom_block->first_mir_insn = insn; 205311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bottom_block->last_mir_insn = orig_block->last_mir_insn; 206311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 20790223cc2e0bfb5a2b55e9ffed896ef327b9f3d2eJunmo Park /* If this block was terminated by a return, conditional branch or throw, 20890223cc2e0bfb5a2b55e9ffed896ef327b9f3d2eJunmo Park * the flag needs to go with the bottom block 20990223cc2e0bfb5a2b55e9ffed896ef327b9f3d2eJunmo Park */ 210311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bottom_block->terminated_by_return = orig_block->terminated_by_return; 211311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee orig_block->terminated_by_return = false; 212311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 21390223cc2e0bfb5a2b55e9ffed896ef327b9f3d2eJunmo Park bottom_block->conditional_branch = orig_block->conditional_branch; 21490223cc2e0bfb5a2b55e9ffed896ef327b9f3d2eJunmo Park orig_block->conditional_branch = false; 21590223cc2e0bfb5a2b55e9ffed896ef327b9f3d2eJunmo Park 21690223cc2e0bfb5a2b55e9ffed896ef327b9f3d2eJunmo Park bottom_block->explicit_throw = orig_block->explicit_throw; 21790223cc2e0bfb5a2b55e9ffed896ef327b9f3d2eJunmo Park orig_block->explicit_throw = false; 21890223cc2e0bfb5a2b55e9ffed896ef327b9f3d2eJunmo Park 219311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* Handle the taken path */ 220311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bottom_block->taken = orig_block->taken; 2210d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (bottom_block->taken != NullBasicBlockId) { 2220d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee orig_block->taken = NullBasicBlockId; 2230d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee BasicBlock* bb_taken = GetBasicBlock(bottom_block->taken); 224e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bb_taken->ErasePredecessor(orig_block->id); 225e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bb_taken->predecessors.push_back(bottom_block->id); 226311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 227311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 228311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* Handle the fallthrough path */ 229311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bottom_block->fall_through = orig_block->fall_through; 2300d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee orig_block->fall_through = bottom_block->id; 231e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bottom_block->predecessors.push_back(orig_block->id); 2320d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (bottom_block->fall_through != NullBasicBlockId) { 2330d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee BasicBlock* bb_fall_through = GetBasicBlock(bottom_block->fall_through); 234e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bb_fall_through->ErasePredecessor(orig_block->id); 235e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bb_fall_through->predecessors.push_back(bottom_block->id); 236311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 237311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 238311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* Handle the successor list */ 2390d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (orig_block->successor_block_list_type != kNotUsed) { 2400d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee bottom_block->successor_block_list_type = orig_block->successor_block_list_type; 241e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bottom_block->successor_blocks.swap(orig_block->successor_blocks); 2420d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee orig_block->successor_block_list_type = kNotUsed; 243e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko DCHECK(orig_block->successor_blocks.empty()); // Empty after the swap() above. 244e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (SuccessorBlockInfo* successor_block_info : bottom_block->successor_blocks) { 2458512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler BasicBlock* bb = GetBasicBlock(successor_block_info->block); 246989367a47b015dd85f850cf756b436fb044b5aeaNiranjan Kumar if (bb != nullptr) { 247e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bb->ErasePredecessor(orig_block->id); 248e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bb->predecessors.push_back(bottom_block->id); 249989367a47b015dd85f850cf756b436fb044b5aeaNiranjan Kumar } 250311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 251311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 252311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 2530d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee orig_block->last_mir_insn = prev; 2543aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler prev->next = nullptr; 255311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 256311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* 257311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Update the immediate predecessor block pointer so that outgoing edges 258311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * can be applied to the proper block. 259311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 260311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (immed_pred_block_p) { 261311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee DCHECK_EQ(*immed_pred_block_p, orig_block); 262311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee *immed_pred_block_p = bottom_block; 263311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 264b48819db07f9a0992a72173380c24249d7fc648abuzbee 265b48819db07f9a0992a72173380c24249d7fc648abuzbee // Associate dex instructions in the bottom block with the new container. 2664376c87eb45b287fad77a16738e76ba28956ab7dVladimir Marko DCHECK(insn != nullptr); 2674376c87eb45b287fad77a16738e76ba28956ab7dVladimir Marko DCHECK(insn != orig_block->first_mir_insn); 2684376c87eb45b287fad77a16738e76ba28956ab7dVladimir Marko DCHECK(insn == bottom_block->first_mir_insn); 2694376c87eb45b287fad77a16738e76ba28956ab7dVladimir Marko DCHECK_EQ(insn->offset, bottom_block->start_offset); 27033c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski // Scan the "bottom" instructions, remapping them to the 27133c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski // newly created "bottom" block. 2724376c87eb45b287fad77a16738e76ba28956ab7dVladimir Marko MIR* p = insn; 27333c17021c74b4e1911851ca89d634d15ed811d8dMathew Zaleski p->bb = bottom_block->id; 2744376c87eb45b287fad77a16738e76ba28956ab7dVladimir Marko while (p != bottom_block->last_mir_insn) { 2754376c87eb45b287fad77a16738e76ba28956ab7dVladimir Marko p = p->next; 2764376c87eb45b287fad77a16738e76ba28956ab7dVladimir Marko DCHECK(p != nullptr); 2773aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler p->bb = bottom_block->id; 278b48819db07f9a0992a72173380c24249d7fc648abuzbee } 279b48819db07f9a0992a72173380c24249d7fc648abuzbee 280311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee return bottom_block; 281311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 282311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 283311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/* 284311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Given a code offset, find out the block that starts with it. If the offset 285311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * is in the middle of an existing block, split it into two. If immed_pred_block_p 286311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * is not non-null and is the block being split, update *immed_pred_block_p to 287311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * point to the bottom block so that outgoing edges can be set up properly 288311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * (by the caller) 289311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Utilizes a map for fast lookup of the typical cases. 290311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 2916a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan RogersBasicBlock* MIRGraph::FindBlock(DexOffset code_offset, bool create, 29272f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu BasicBlock** immed_pred_block_p, 29372f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu ScopedArenaVector<uint16_t>* dex_pc_to_block_map) { 29422c2d74f4c641feaf22a520d2a0538b31a82239dCalin Juravle if (UNLIKELY(code_offset >= current_code_item_->insns_size_in_code_units_)) { 29522c2d74f4c641feaf22a520d2a0538b31a82239dCalin Juravle // There can be a fall-through out of the method code. We shall record such a block 29622c2d74f4c641feaf22a520d2a0538b31a82239dCalin Juravle // here (assuming create==true) and check that it's dead at the end of InlineMethod(). 29722c2d74f4c641feaf22a520d2a0538b31a82239dCalin Juravle // Though we're only aware of the cases where code_offset is exactly the same as 29822c2d74f4c641feaf22a520d2a0538b31a82239dCalin Juravle // insns_size_in_code_units_, treat greater code_offset the same just in case. 29922c2d74f4c641feaf22a520d2a0538b31a82239dCalin Juravle code_offset = current_code_item_->insns_size_in_code_units_; 300311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 301b48819db07f9a0992a72173380c24249d7fc648abuzbee 30272f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu int block_id = (*dex_pc_to_block_map)[code_offset]; 303e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* bb = GetBasicBlock(block_id); 304b48819db07f9a0992a72173380c24249d7fc648abuzbee 3056a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers if ((bb != nullptr) && (bb->start_offset == code_offset)) { 306b48819db07f9a0992a72173380c24249d7fc648abuzbee // Does this containing block start with the desired instruction? 307bd663de599b16229085759366c56e2ed5a1dc7ecbuzbee return bb; 308bd663de599b16229085759366c56e2ed5a1dc7ecbuzbee } 309311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 310b48819db07f9a0992a72173380c24249d7fc648abuzbee // No direct hit. 311b48819db07f9a0992a72173380c24249d7fc648abuzbee if (!create) { 3126a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers return nullptr; 313b48819db07f9a0992a72173380c24249d7fc648abuzbee } 314b48819db07f9a0992a72173380c24249d7fc648abuzbee 3156a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers if (bb != nullptr) { 316b48819db07f9a0992a72173380c24249d7fc648abuzbee // The target exists somewhere in an existing block. 31772f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu BasicBlock* bottom_block = SplitBlock(code_offset, bb, bb == *immed_pred_block_p ? immed_pred_block_p : nullptr); 31872f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu DCHECK(bottom_block != nullptr); 31972f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu MIR* p = bottom_block->first_mir_insn; 32072f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu BasicBlock* orig_block = bb; 32172f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu DCHECK_EQ((*dex_pc_to_block_map)[p->offset], orig_block->id); 32272f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu // Scan the "bottom" instructions, remapping them to the 32372f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu // newly created "bottom" block. 32472f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu (*dex_pc_to_block_map)[p->offset] = bottom_block->id; 32572f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu while (p != bottom_block->last_mir_insn) { 32672f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu p = p->next; 32772f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu DCHECK(p != nullptr); 32872f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu int opcode = p->dalvikInsn.opcode; 32972f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu /* 33072f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu * Some messiness here to ensure that we only enter real opcodes and only the 33172f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu * first half of a potentially throwing instruction that has been split into 33272f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu * CHECK and work portions. Since the 2nd half of a split operation is always 33372f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu * the first in a BasicBlock, we can't hit it here. 33472f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu */ 33572f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu if ((opcode == kMirOpCheck) || !MIR::DecodedInstruction::IsPseudoMirOp(opcode)) { 33672f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu BasicBlockId mapped_id = (*dex_pc_to_block_map)[p->offset]; 33772f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu // At first glance the instructions should all be mapped to orig_block. 33872f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu // However, multiple instructions may correspond to the same dex, hence an earlier 33972f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu // instruction may have already moved the mapping for dex to bottom_block. 34072f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu DCHECK((mapped_id == orig_block->id) || (mapped_id == bottom_block->id)); 34172f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu (*dex_pc_to_block_map)[p->offset] = bottom_block->id; 34272f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu } 34372f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu } 34472f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu return bottom_block; 345311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 346311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 347b48819db07f9a0992a72173380c24249d7fc648abuzbee // Create a new block. 348e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bb = CreateNewBB(kDalvikByteCode); 349311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bb->start_offset = code_offset; 35072f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu (*dex_pc_to_block_map)[bb->start_offset] = bb->id; 351311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee return bb; 352311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 353311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 354b48819db07f9a0992a72173380c24249d7fc648abuzbee 355311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/* Identify code range in try blocks and set up the empty catch blocks */ 35672f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fuvoid MIRGraph::ProcessTryCatchBlocks(ScopedArenaVector<uint16_t>* dex_pc_to_block_map) { 357311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int tries_size = current_code_item_->tries_size_; 3580d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DexOffset offset; 359311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 360311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (tries_size == 0) { 361311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee return; 362311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 363311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 364311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (int i = 0; i < tries_size; i++) { 365311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee const DexFile::TryItem* pTry = 366311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee DexFile::GetTryItems(*current_code_item_, i); 3670d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DexOffset start_offset = pTry->start_addr_; 3680d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DexOffset end_offset = start_offset + pTry->insn_count_; 369311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (offset = start_offset; offset < end_offset; offset++) { 370862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee try_block_addr_->SetBit(offset); 371311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 372311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 373311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 3748512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Iterate over each of the handlers to enqueue the empty Catch blocks. 37513735955f39b3b304c37d2b2840663c131262c18Ian Rogers const uint8_t* handlers_ptr = DexFile::GetCatchHandlerData(*current_code_item_, 0); 376311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr); 377311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (uint32_t idx = 0; idx < handlers_size; idx++) { 378311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee CatchHandlerIterator iterator(handlers_ptr); 379311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (; iterator.HasNext(); iterator.Next()) { 380311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee uint32_t address = iterator.GetHandlerAddress(); 38172f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu FindBlock(address, true /*create*/, /* immed_pred_block_p */ nullptr, dex_pc_to_block_map); 382311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 383311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee handlers_ptr = iterator.EndDataPointer(); 384311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 385311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 386311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 387e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Markobool MIRGraph::IsBadMonitorExitCatch(NarrowDexOffset monitor_exit_offset, 388e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko NarrowDexOffset catch_offset) { 389e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko // Catches for monitor-exit during stack unwinding have the pattern 390e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko // move-exception (move)* (goto)? monitor-exit throw 391e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko // In the currently generated dex bytecode we see these catching a bytecode range including 392e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko // either its own or an identical monitor-exit, http://b/15745363 . This function checks if 393e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko // it's the case for a given monitor-exit and catch block so that we can ignore it. 394e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko // (We don't want to ignore all monitor-exit catches since one could enclose a synchronized 395e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko // block in a try-block and catch the NPE, Error or Throwable and we should let it through; 396e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko // even though a throwing monitor-exit certainly indicates a bytecode error.) 39709ae022f55ab27edf4802baf7a05e76d7dc823a9Razvan A Lupusoru const Instruction* monitor_exit = Instruction::At(current_code_item_->insns_ + monitor_exit_offset); 398e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko DCHECK(monitor_exit->Opcode() == Instruction::MONITOR_EXIT); 399e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko int monitor_reg = monitor_exit->VRegA_11x(); 40009ae022f55ab27edf4802baf7a05e76d7dc823a9Razvan A Lupusoru const Instruction* check_insn = Instruction::At(current_code_item_->insns_ + catch_offset); 40107c6f5a3eb17e08f3f2d850e130896f63c80911fVladimir Marko if (check_insn->Opcode() == Instruction::MOVE_EXCEPTION) { 40207c6f5a3eb17e08f3f2d850e130896f63c80911fVladimir Marko if (check_insn->VRegA_11x() == monitor_reg) { 40307c6f5a3eb17e08f3f2d850e130896f63c80911fVladimir Marko // Unexpected move-exception to the same register. Probably not the pattern we're looking for. 40407c6f5a3eb17e08f3f2d850e130896f63c80911fVladimir Marko return false; 40507c6f5a3eb17e08f3f2d850e130896f63c80911fVladimir Marko } 40607c6f5a3eb17e08f3f2d850e130896f63c80911fVladimir Marko check_insn = check_insn->Next(); 407e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko } 408e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko while (true) { 409e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko int dest = -1; 410e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko bool wide = false; 411e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko switch (check_insn->Opcode()) { 412e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::MOVE_WIDE: 413e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko wide = true; 414fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers FALLTHROUGH_INTENDED; 415e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::MOVE_OBJECT: 416e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::MOVE: 417e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko dest = check_insn->VRegA_12x(); 418e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko break; 419e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko 420e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::MOVE_WIDE_FROM16: 421e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko wide = true; 422fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers FALLTHROUGH_INTENDED; 423e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::MOVE_OBJECT_FROM16: 424e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::MOVE_FROM16: 425e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko dest = check_insn->VRegA_22x(); 426e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko break; 427e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko 428e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::MOVE_WIDE_16: 429e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko wide = true; 430fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers FALLTHROUGH_INTENDED; 431e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::MOVE_OBJECT_16: 432e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::MOVE_16: 433e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko dest = check_insn->VRegA_32x(); 434e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko break; 435e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko 436e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::GOTO: 437e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::GOTO_16: 438e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko case Instruction::GOTO_32: 439e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko check_insn = check_insn->RelativeAt(check_insn->GetTargetOffset()); 440fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers FALLTHROUGH_INTENDED; 441e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko default: 442e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko return check_insn->Opcode() == Instruction::MONITOR_EXIT && 443e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko check_insn->VRegA_11x() == monitor_reg; 444e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko } 445e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko 446e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko if (dest == monitor_reg || (wide && dest + 1 == monitor_reg)) { 447e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko return false; 448e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko } 449e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko 450e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko check_insn = check_insn->Next(); 451e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko } 452e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko} 453e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko 454311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/* Process instructions with the kBranch flag */ 4550d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeBasicBlock* MIRGraph::ProcessCanBranch(BasicBlock* cur_block, MIR* insn, DexOffset cur_offset, 4560d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee int width, int flags, const uint16_t* code_ptr, 45772f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu const uint16_t* code_end, 45872f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu ScopedArenaVector<uint16_t>* dex_pc_to_block_map) { 4590d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DexOffset target = cur_offset; 460311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee switch (insn->dalvikInsn.opcode) { 461311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::GOTO: 462311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::GOTO_16: 463311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::GOTO_32: 464311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee target += insn->dalvikInsn.vA; 465311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee break; 466311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_EQ: 467311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_NE: 468311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_LT: 469311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_GE: 470311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_GT: 471311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_LE: 472311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cur_block->conditional_branch = true; 473311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee target += insn->dalvikInsn.vC; 474311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee break; 475311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_EQZ: 476311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_NEZ: 477311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_LTZ: 478311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_GEZ: 479311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_GTZ: 480311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee case Instruction::IF_LEZ: 481311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cur_block->conditional_branch = true; 482311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee target += insn->dalvikInsn.vB; 483311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee break; 484311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee default: 485311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee LOG(FATAL) << "Unexpected opcode(" << insn->dalvikInsn.opcode << ") with kBranch set"; 486311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 487b48819db07f9a0992a72173380c24249d7fc648abuzbee CountBranch(target); 4886a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers BasicBlock* taken_block = FindBlock(target, /* create */ true, 48972f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu /* immed_pred_block_p */ &cur_block, 49072f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu dex_pc_to_block_map); 49122c2d74f4c641feaf22a520d2a0538b31a82239dCalin Juravle DCHECK(taken_block != nullptr); 4920d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee cur_block->taken = taken_block->id; 493e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko taken_block->predecessors.push_back(cur_block->id); 494311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 495311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* Always terminate the current block for conditional branches */ 496311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (flags & Instruction::kContinue) { 4972469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler BasicBlock* fallthrough_block = FindBlock(cur_offset + width, 498311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* create */ 499311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee true, 500311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* immed_pred_block_p */ 50172f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu &cur_block, 50272f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu dex_pc_to_block_map); 50322c2d74f4c641feaf22a520d2a0538b31a82239dCalin Juravle DCHECK(fallthrough_block != nullptr); 5040d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee cur_block->fall_through = fallthrough_block->id; 505e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko fallthrough_block->predecessors.push_back(cur_block->id); 506311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } else if (code_ptr < code_end) { 50772f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu FindBlock(cur_offset + width, /* create */ true, /* immed_pred_block_p */ nullptr, dex_pc_to_block_map); 508311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 509311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee return cur_block; 510311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 511311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 512311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/* Process instructions with the kSwitch flag */ 51317189ac098b2f156713db1821b49db7b2f018bbebuzbeeBasicBlock* MIRGraph::ProcessCanSwitch(BasicBlock* cur_block, MIR* insn, DexOffset cur_offset, 51472f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu int width, int flags, 51572f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu ScopedArenaVector<uint16_t>* dex_pc_to_block_map) { 5166a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers UNUSED(flags); 517311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee const uint16_t* switch_data = 51822c2d74f4c641feaf22a520d2a0538b31a82239dCalin Juravle reinterpret_cast<const uint16_t*>(GetCurrentInsns() + cur_offset + 51922c2d74f4c641feaf22a520d2a0538b31a82239dCalin Juravle static_cast<int32_t>(insn->dalvikInsn.vB)); 520311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int size; 521311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee const int* keyTable; 522311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee const int* target_table; 523311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int i; 524311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int first_key; 525311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 526311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* 527311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Packed switch data format: 528311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * ushort ident = 0x0100 magic value 529311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * ushort size number of entries in the table 530311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * int first_key first (and lowest) switch case value 531311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * int targets[size] branch targets, relative to switch opcode 532311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * 533311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Total size is (4+size*2) 16-bit code units. 534311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 535311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (insn->dalvikInsn.opcode == Instruction::PACKED_SWITCH) { 536311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee DCHECK_EQ(static_cast<int>(switch_data[0]), 537311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee static_cast<int>(Instruction::kPackedSwitchSignature)); 538311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee size = switch_data[1]; 539311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee first_key = switch_data[2] | (switch_data[3] << 16); 540311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee target_table = reinterpret_cast<const int*>(&switch_data[4]); 5412cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier keyTable = nullptr; // Make the compiler happy. 542311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* 543311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Sparse switch data format: 544311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * ushort ident = 0x0200 magic value 545311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * ushort size number of entries in the table; > 0 546311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * int keys[size] keys, sorted low-to-high; 32-bit aligned 547311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * int targets[size] branch targets, relative to switch opcode 548311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * 549311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Total size is (2+size*4) 16-bit code units. 550311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 551311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } else { 552311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee DCHECK_EQ(static_cast<int>(switch_data[0]), 553311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee static_cast<int>(Instruction::kSparseSwitchSignature)); 554311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee size = switch_data[1]; 555311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee keyTable = reinterpret_cast<const int*>(&switch_data[2]); 556311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee target_table = reinterpret_cast<const int*>(&switch_data[2 + size*2]); 5578512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler first_key = 0; // To make the compiler happy. 558311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 559311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 5600d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (cur_block->successor_block_list_type != kNotUsed) { 561311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee LOG(FATAL) << "Successor block list already in use: " 5620d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee << static_cast<int>(cur_block->successor_block_list_type); 563311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 5640d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee cur_block->successor_block_list_type = 5650d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee (insn->dalvikInsn.opcode == Instruction::PACKED_SWITCH) ? kPackedSwitch : kSparseSwitch; 566e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko cur_block->successor_blocks.reserve(size); 567311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 568311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (i = 0; i < size; i++) { 5696a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers BasicBlock* case_block = FindBlock(cur_offset + target_table[i], /* create */ true, 57072f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu /* immed_pred_block_p */ &cur_block, 57172f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu dex_pc_to_block_map); 57222c2d74f4c641feaf22a520d2a0538b31a82239dCalin Juravle DCHECK(case_block != nullptr); 5738512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler SuccessorBlockInfo* successor_block_info = 574f6c4b3ba3825de1dbb3e747a68b809c6cc8eb4dbMathieu Chartier static_cast<SuccessorBlockInfo*>(arena_->Alloc(sizeof(SuccessorBlockInfo), 57583cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko kArenaAllocSuccessor)); 5760d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee successor_block_info->block = case_block->id; 577311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee successor_block_info->key = 578311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee (insn->dalvikInsn.opcode == Instruction::PACKED_SWITCH) ? 579311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee first_key + i : keyTable[i]; 580e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko cur_block->successor_blocks.push_back(successor_block_info); 581e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko case_block->predecessors.push_back(cur_block->id); 582311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 583311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 584311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* Fall-through case */ 5856a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers BasicBlock* fallthrough_block = FindBlock(cur_offset + width, /* create */ true, 58672f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu /* immed_pred_block_p */ nullptr, 58772f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu dex_pc_to_block_map); 58822c2d74f4c641feaf22a520d2a0538b31a82239dCalin Juravle DCHECK(fallthrough_block != nullptr); 5890d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee cur_block->fall_through = fallthrough_block->id; 590e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko fallthrough_block->predecessors.push_back(cur_block->id); 59117189ac098b2f156713db1821b49db7b2f018bbebuzbee return cur_block; 592311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 593311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 594311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/* Process instructions with the kThrow flag */ 5950d82948094d9a198e01aa95f64012bdedd5b6fc9buzbeeBasicBlock* MIRGraph::ProcessCanThrow(BasicBlock* cur_block, MIR* insn, DexOffset cur_offset, 5960d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee int width, int flags, ArenaBitVector* try_block_addr, 59772f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu const uint16_t* code_ptr, const uint16_t* code_end, 59872f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu ScopedArenaVector<uint16_t>* dex_pc_to_block_map) { 5996a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers UNUSED(flags); 600862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee bool in_try_block = try_block_addr->IsBitSet(cur_offset); 60117189ac098b2f156713db1821b49db7b2f018bbebuzbee bool is_throw = (insn->dalvikInsn.opcode == Instruction::THROW); 602311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 603311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* In try block */ 604311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (in_try_block) { 605311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee CatchHandlerIterator iterator(*current_code_item_, cur_offset); 606311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 6070d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (cur_block->successor_block_list_type != kNotUsed) { 608311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee LOG(INFO) << PrettyMethod(cu_->method_idx, *cu_->dex_file); 609311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee LOG(FATAL) << "Successor block list already in use: " 6100d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee << static_cast<int>(cur_block->successor_block_list_type); 611311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 612311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 61302c8cc6d1312a2b55533f02f6369dc7c94672f90Brian Carlstrom for (; iterator.HasNext(); iterator.Next()) { 6146a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers BasicBlock* catch_block = FindBlock(iterator.GetHandlerAddress(), false /* create */, 61572f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu nullptr /* immed_pred_block_p */, 61672f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu dex_pc_to_block_map); 617e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko if (insn->dalvikInsn.opcode == Instruction::MONITOR_EXIT && 618e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko IsBadMonitorExitCatch(insn->offset, catch_block->start_offset)) { 619e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko // Don't allow monitor-exit to catch its own exception, http://b/15745363 . 620e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko continue; 621e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko } 622e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko if (cur_block->successor_block_list_type == kNotUsed) { 623e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko cur_block->successor_block_list_type = kCatch; 624e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko } 625311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee catch_block->catch_entry = true; 626311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (kIsDebugBuild) { 627311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee catches_.insert(catch_block->start_offset); 628311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 6298512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler SuccessorBlockInfo* successor_block_info = reinterpret_cast<SuccessorBlockInfo*> 63083cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko (arena_->Alloc(sizeof(SuccessorBlockInfo), kArenaAllocSuccessor)); 6310d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee successor_block_info->block = catch_block->id; 632311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee successor_block_info->key = iterator.GetHandlerTypeIndex(); 633e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko cur_block->successor_blocks.push_back(successor_block_info); 634e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko catch_block->predecessors.push_back(cur_block->id); 635311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 636e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko in_try_block = (cur_block->successor_block_list_type != kNotUsed); 637e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko } 638e767f6ce3997f7634b26e7651bc7b90c060d3965Vladimir Marko bool build_all_edges = 639e767f6ce3997f7634b26e7651bc7b90c060d3965Vladimir Marko (cu_->disable_opt & (1 << kSuppressExceptionEdges)) || is_throw || in_try_block; 640e8ae81453e1d6c19d7db2001a1e7b1849f74241cVladimir Marko if (!in_try_block && build_all_edges) { 641e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* eh_block = CreateNewBB(kExceptionHandling); 6420d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee cur_block->taken = eh_block->id; 643311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee eh_block->start_offset = cur_offset; 644e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko eh_block->predecessors.push_back(cur_block->id); 645311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 646311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 64717189ac098b2f156713db1821b49db7b2f018bbebuzbee if (is_throw) { 648311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cur_block->explicit_throw = true; 6492724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee if (code_ptr < code_end) { 6508512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Force creation of new block following THROW via side-effect. 65172f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu FindBlock(cur_offset + width, /* create */ true, /* immed_pred_block_p */ nullptr, dex_pc_to_block_map); 652311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 653311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (!in_try_block) { 654311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee // Don't split a THROW that can't rethrow - we're done. 655311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee return cur_block; 656311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 657311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 658311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 65917189ac098b2f156713db1821b49db7b2f018bbebuzbee if (!build_all_edges) { 66017189ac098b2f156713db1821b49db7b2f018bbebuzbee /* 66117189ac098b2f156713db1821b49db7b2f018bbebuzbee * Even though there is an exception edge here, control cannot return to this 66217189ac098b2f156713db1821b49db7b2f018bbebuzbee * method. Thus, for the purposes of dataflow analysis and optimization, we can 66317189ac098b2f156713db1821b49db7b2f018bbebuzbee * ignore the edge. Doing this reduces compile time, and increases the scope 66417189ac098b2f156713db1821b49db7b2f018bbebuzbee * of the basic-block level optimization pass. 66517189ac098b2f156713db1821b49db7b2f018bbebuzbee */ 66617189ac098b2f156713db1821b49db7b2f018bbebuzbee return cur_block; 66717189ac098b2f156713db1821b49db7b2f018bbebuzbee } 66817189ac098b2f156713db1821b49db7b2f018bbebuzbee 669311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* 670311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Split the potentially-throwing instruction into two parts. 671311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * The first half will be a pseudo-op that captures the exception 672311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * edges and terminates the basic block. It always falls through. 673311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Then, create a new basic block that begins with the throwing instruction 674311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * (minus exceptions). Note: this new basic block must NOT be entered into 675311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * the block_map. If the potentially-throwing instruction is the target of a 676311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * future branch, we need to find the check psuedo half. The new 677311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * basic block containing the work portion of the instruction should 678311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * only be entered via fallthrough from the block containing the 679311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * pseudo exception edge MIR. Note also that this new block is 680311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * not automatically terminated after the work portion, and may 681311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * contain following instructions. 682b48819db07f9a0992a72173380c24249d7fc648abuzbee * 68372f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu * Note also that the dex_pc_to_block_map entry for the potentially 684b48819db07f9a0992a72173380c24249d7fc648abuzbee * throwing instruction will refer to the original basic block. 685311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 686e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* new_block = CreateNewBB(kDalvikByteCode); 687311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee new_block->start_offset = insn->offset; 6880d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee cur_block->fall_through = new_block->id; 689e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko new_block->predecessors.push_back(cur_block->id); 6903aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler MIR* new_insn = NewMIR(); 691311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee *new_insn = *insn; 69235ba7f3a78d38885ec54e61ed060d2771eeceea7buzbee insn->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpCheck); 6938512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Associate the two halves. 694311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee insn->meta.throw_insn = new_insn; 695cdacac4a8196bdc620185079ec9e886329606f3dJean Christophe Beyler new_block->AppendMIR(new_insn); 696311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee return new_block; 697311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 698311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 699311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/* Parse a Dex method and insert it into the MIRGraph at the current insert point. */ 700311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeevoid MIRGraph::InlineMethod(const DexFile::CodeItem* code_item, uint32_t access_flags, 70120f85597828194c12be10d3a927999def066555eVladimir Marko InvokeType invoke_type ATTRIBUTE_UNUSED, uint16_t class_def_idx, 7022ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom uint32_t method_idx, jobject class_loader, const DexFile& dex_file) { 703311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee current_code_item_ = code_item; 704311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee method_stack_.push_back(std::make_pair(current_method_, current_offset_)); 705311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee current_method_ = m_units_.size(); 706311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee current_offset_ = 0; 707311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee // TODO: will need to snapshot stack image and use that as the mir context identification. 708c91df2d6339dd4adf2da582372451df19ce2ff44Vladimir Marko m_units_.push_back(new (arena_) DexCompilationUnit( 709c91df2d6339dd4adf2da582372451df19ce2ff44Vladimir Marko cu_, class_loader, Runtime::Current()->GetClassLinker(), dex_file, 710c91df2d6339dd4adf2da582372451df19ce2ff44Vladimir Marko current_code_item_, class_def_idx, method_idx, access_flags, 711c91df2d6339dd4adf2da582372451df19ce2ff44Vladimir Marko cu_->compiler_driver->GetVerifiedMethod(&dex_file, method_idx))); 712311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee const uint16_t* code_ptr = current_code_item_->insns_; 713311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee const uint16_t* code_end = 714311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee current_code_item_->insns_ + current_code_item_->insns_size_in_code_units_; 715311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 716311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee // TODO: need to rework expansion of block list & try_block_addr when inlining activated. 717b48819db07f9a0992a72173380c24249d7fc648abuzbee // TUNING: use better estimate of basic blocks for following resize. 718e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko block_list_.reserve(block_list_.size() + current_code_item_->insns_size_in_code_units_); 71972f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu // FindBlock lookup cache. 72072f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu ScopedArenaAllocator allocator(&cu_->arena_stack); 72172f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu ScopedArenaVector<uint16_t> dex_pc_to_block_map(allocator.Adapter()); 72222c2d74f4c641feaf22a520d2a0538b31a82239dCalin Juravle dex_pc_to_block_map.resize(current_code_item_->insns_size_in_code_units_ + 72322c2d74f4c641feaf22a520d2a0538b31a82239dCalin Juravle 1 /* Fall-through on last insn; dead or punt to interpreter. */); 724bd663de599b16229085759366c56e2ed5a1dc7ecbuzbee 725311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee // TODO: replace with explicit resize routine. Using automatic extension side effect for now. 726862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee try_block_addr_->SetBit(current_code_item_->insns_size_in_code_units_); 727862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee try_block_addr_->ClearBit(current_code_item_->insns_size_in_code_units_); 728311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 729311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee // If this is the first method, set up default entry and exit blocks. 730311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (current_method_ == 0) { 7312cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier DCHECK(entry_block_ == nullptr); 7322cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier DCHECK(exit_block_ == nullptr); 733ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko DCHECK_EQ(GetNumBlocks(), 0U); 7340d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // Use id 0 to represent a null block. 735e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* null_block = CreateNewBB(kNullBlock); 7360d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DCHECK_EQ(null_block->id, NullBasicBlockId); 7370d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee null_block->hidden = true; 738e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko entry_block_ = CreateNewBB(kEntryBlock); 739e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko exit_block_ = CreateNewBB(kExitBlock); 740311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } else { 741311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee UNIMPLEMENTED(FATAL) << "Nested inlining not implemented."; 742311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* 743311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Will need to manage storage for ins & outs, push prevous state and update 744311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * insert point. 745311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 746311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 747311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 748311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* Current block to record parsed instructions */ 749e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* cur_block = CreateNewBB(kDalvikByteCode); 7500d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DCHECK_EQ(current_offset_, 0U); 751311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cur_block->start_offset = current_offset_; 7520d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee // TODO: for inlining support, insert at the insert point rather than entry block. 7530d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee entry_block_->fall_through = cur_block->id; 754e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko cur_block->predecessors.push_back(entry_block_->id); 755311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 7563d73ba2ce682edfaf41f29521bd6039c6499a1c5Vladimir Marko /* Identify code range in try blocks and set up the empty catch blocks */ 75772f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu ProcessTryCatchBlocks(&dex_pc_to_block_map); 758311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 7593d73ba2ce682edfaf41f29521bd6039c6499a1c5Vladimir Marko uint64_t merged_df_flags = 0u; 7603d73ba2ce682edfaf41f29521bd6039c6499a1c5Vladimir Marko 761311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* Parse all instructions and put them into containing basic blocks */ 762311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee while (code_ptr < code_end) { 7633aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler MIR *insn = NewMIR(); 764311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee insn->offset = current_offset_; 765311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee insn->m_unit_index = current_method_; 766311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int width = ParseInsn(code_ptr, &insn->dalvikInsn); 767311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee Instruction::Code opcode = insn->dalvikInsn.opcode; 7682cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (opcode_count_ != nullptr) { 769311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee opcode_count_[static_cast<int>(opcode)]++; 770311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 771311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 772fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler int flags = insn->dalvikInsn.FlagsOf(); 773b1f1d642093418612c0a27ce4203b421bb6eb767buzbee int verify_flags = Instruction::VerifyFlagsOf(insn->dalvikInsn.opcode); 774311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 775cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler uint64_t df_flags = GetDataFlowAttributes(insn); 7763d73ba2ce682edfaf41f29521bd6039c6499a1c5Vladimir Marko merged_df_flags |= df_flags; 777311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 778311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (df_flags & DF_HAS_DEFS) { 779311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee def_count_ += (df_flags & DF_A_WIDE) ? 2 : 1; 780311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 781311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 7821da1e2fceb0030b4b76b43510b1710a9613e0c2ebuzbee if (df_flags & DF_LVN) { 7831da1e2fceb0030b4b76b43510b1710a9613e0c2ebuzbee cur_block->use_lvn = true; // Run local value numbering on this basic block. 7841da1e2fceb0030b4b76b43510b1710a9613e0c2ebuzbee } 7851da1e2fceb0030b4b76b43510b1710a9613e0c2ebuzbee 7868512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Check for inline data block signatures. 7872724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee if (opcode == Instruction::NOP) { 7882724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee // A simple NOP will have a width of 1 at this point, embedded data NOP > 1. 7892724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee if ((width == 1) && ((current_offset_ & 0x1) == 0x1) && ((code_end - code_ptr) > 1)) { 7902724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee // Could be an aligning nop. If an embedded data NOP follows, treat pair as single unit. 7912724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee uint16_t following_raw_instruction = code_ptr[1]; 7922724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee if ((following_raw_instruction == Instruction::kSparseSwitchSignature) || 7932724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee (following_raw_instruction == Instruction::kPackedSwitchSignature) || 7942724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee (following_raw_instruction == Instruction::kArrayDataSignature)) { 7952724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee width += Instruction::At(code_ptr + 1)->SizeInCodeUnits(); 7962724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee } 7972724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee } 7982724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee if (width == 1) { 7992724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee // It is a simple nop - treat normally. 800cdacac4a8196bdc620185079ec9e886329606f3dJean Christophe Beyler cur_block->AppendMIR(insn); 8012724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee } else { 8020d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DCHECK(cur_block->fall_through == NullBasicBlockId); 8030d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DCHECK(cur_block->taken == NullBasicBlockId); 8046489d22a44ea7d135c142ee94925570d0333d5e7buzbee // Unreachable instruction, mark for no continuation and end basic block. 8052724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee flags &= ~Instruction::kContinue; 80672f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu FindBlock(current_offset_ + width, /* create */ true, 80772f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu /* immed_pred_block_p */ nullptr, &dex_pc_to_block_map); 8082724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee } 8092724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee } else { 810cdacac4a8196bdc620185079ec9e886329606f3dJean Christophe Beyler cur_block->AppendMIR(insn); 8112724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee } 8122724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee 813b48819db07f9a0992a72173380c24249d7fc648abuzbee // Associate the starting dex_pc for this opcode with its containing basic block. 81472f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu dex_pc_to_block_map[insn->offset] = cur_block->id; 815b48819db07f9a0992a72173380c24249d7fc648abuzbee 8162724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee code_ptr += width; 8172724776ad521eebb1c7f0e4be56d6e6ab4764f86buzbee 818311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (flags & Instruction::kBranch) { 819311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cur_block = ProcessCanBranch(cur_block, insn, current_offset_, 82072f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu width, flags, code_ptr, code_end, &dex_pc_to_block_map); 821311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } else if (flags & Instruction::kReturn) { 822311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cur_block->terminated_by_return = true; 8230d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee cur_block->fall_through = exit_block_->id; 824e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko exit_block_->predecessors.push_back(cur_block->id); 825311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* 826311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Terminate the current block if there are instructions 827311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * afterwards. 828311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 829311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (code_ptr < code_end) { 830311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* 831311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Create a fallthrough block for real instructions 832311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * (incl. NOP). 833311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 83472f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu FindBlock(current_offset_ + width, /* create */ true, 83572f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu /* immed_pred_block_p */ nullptr, &dex_pc_to_block_map); 836311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 837311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } else if (flags & Instruction::kThrow) { 838311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cur_block = ProcessCanThrow(cur_block, insn, current_offset_, width, flags, try_block_addr_, 83972f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu code_ptr, code_end, &dex_pc_to_block_map); 840311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } else if (flags & Instruction::kSwitch) { 84172f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu cur_block = ProcessCanSwitch(cur_block, insn, current_offset_, width, 84272f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu flags, &dex_pc_to_block_map); 843311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 844688e7c5c9f36573dd4da2edd889470d930b0054bAlexei Zavjalov if (verify_flags & Instruction::kVerifyVarArgRange || 845688e7c5c9f36573dd4da2edd889470d930b0054bAlexei Zavjalov verify_flags & Instruction::kVerifyVarArgRangeNonZero) { 846b1f1d642093418612c0a27ce4203b421bb6eb767buzbee /* 847b1f1d642093418612c0a27ce4203b421bb6eb767buzbee * The Quick backend's runtime model includes a gap between a method's 848b1f1d642093418612c0a27ce4203b421bb6eb767buzbee * argument ("in") vregs and the rest of its vregs. Handling a range instruction 849b1f1d642093418612c0a27ce4203b421bb6eb767buzbee * which spans the gap is somewhat complicated, and should not happen 850b1f1d642093418612c0a27ce4203b421bb6eb767buzbee * in normal usage of dx. Punt to the interpreter. 851b1f1d642093418612c0a27ce4203b421bb6eb767buzbee */ 852b1f1d642093418612c0a27ce4203b421bb6eb767buzbee int first_reg_in_range = insn->dalvikInsn.vC; 853b1f1d642093418612c0a27ce4203b421bb6eb767buzbee int last_reg_in_range = first_reg_in_range + insn->dalvikInsn.vA - 1; 854b1f1d642093418612c0a27ce4203b421bb6eb767buzbee if (IsInVReg(first_reg_in_range) != IsInVReg(last_reg_in_range)) { 855b1f1d642093418612c0a27ce4203b421bb6eb767buzbee punt_to_interpreter_ = true; 856b1f1d642093418612c0a27ce4203b421bb6eb767buzbee } 857b1f1d642093418612c0a27ce4203b421bb6eb767buzbee } 858311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee current_offset_ += width; 8596a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers BasicBlock* next_block = FindBlock(current_offset_, /* create */ false, 86072f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu /* immed_pred_block_p */ nullptr, 86172f53af0307b9109a1cfc0671675ce5d45c66d3aChao-ying Fu &dex_pc_to_block_map); 862311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (next_block) { 863311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* 864311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * The next instruction could be the target of a previously parsed 865311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * forward branch so a block is already created. If the current 866311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * instruction is not an unconditional branch, connect them through 867311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * the fall-through link. 868311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */ 8690d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee DCHECK(cur_block->fall_through == NullBasicBlockId || 8700d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee GetBasicBlock(cur_block->fall_through) == next_block || 8710d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee GetBasicBlock(cur_block->fall_through) == exit_block_); 872311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 8730d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if ((cur_block->fall_through == NullBasicBlockId) && (flags & Instruction::kContinue)) { 8740d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee cur_block->fall_through = next_block->id; 875e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko next_block->predecessors.push_back(cur_block->id); 876311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 877311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee cur_block = next_block; 878311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 879311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 8803d73ba2ce682edfaf41f29521bd6039c6499a1c5Vladimir Marko merged_df_flags_ = merged_df_flags; 8815816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko 882311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (cu_->enable_debug & (1 << kDebugDumpCFG)) { 883311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee DumpCFG("/sdcard/1_post_parse_cfg/", true); 884311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 885311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 886311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (cu_->verbose) { 8871fd3346740dfb7f47be9922312b68a4227fada96buzbee DumpMIRGraph(); 888311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 88922c2d74f4c641feaf22a520d2a0538b31a82239dCalin Juravle 89022c2d74f4c641feaf22a520d2a0538b31a82239dCalin Juravle // Check if there's been a fall-through out of the method code. 89122c2d74f4c641feaf22a520d2a0538b31a82239dCalin Juravle BasicBlockId out_bb_id = dex_pc_to_block_map[current_code_item_->insns_size_in_code_units_]; 89222c2d74f4c641feaf22a520d2a0538b31a82239dCalin Juravle if (UNLIKELY(out_bb_id != NullBasicBlockId)) { 89322c2d74f4c641feaf22a520d2a0538b31a82239dCalin Juravle // Eagerly calculate DFS order to determine if the block is dead. 89422c2d74f4c641feaf22a520d2a0538b31a82239dCalin Juravle DCHECK(!DfsOrdersUpToDate()); 89522c2d74f4c641feaf22a520d2a0538b31a82239dCalin Juravle ComputeDFSOrders(); 89622c2d74f4c641feaf22a520d2a0538b31a82239dCalin Juravle BasicBlock* out_bb = GetBasicBlock(out_bb_id); 89722c2d74f4c641feaf22a520d2a0538b31a82239dCalin Juravle DCHECK(out_bb != nullptr); 89822c2d74f4c641feaf22a520d2a0538b31a82239dCalin Juravle if (out_bb->block_type != kDead) { 89922c2d74f4c641feaf22a520d2a0538b31a82239dCalin Juravle LOG(WARNING) << "Live fall-through out of method in " << PrettyMethod(method_idx, dex_file); 90022c2d74f4c641feaf22a520d2a0538b31a82239dCalin Juravle SetPuntToInterpreter(true); 90122c2d74f4c641feaf22a520d2a0538b31a82239dCalin Juravle } 90222c2d74f4c641feaf22a520d2a0538b31a82239dCalin Juravle } 903311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 904311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 9052ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MIRGraph::ShowOpcodeStats() { 9062cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier DCHECK(opcode_count_ != nullptr); 907311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee LOG(INFO) << "Opcode Count"; 908311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (int i = 0; i < kNumPackedOpcodes; i++) { 909311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (opcode_count_[i] != 0) { 910311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee LOG(INFO) << "-C- " << Instruction::Name(static_cast<Instruction::Code>(i)) 911311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee << " " << opcode_count_[i]; 912311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 913311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 914311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 915311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 916cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyleruint64_t MIRGraph::GetDataFlowAttributes(Instruction::Code opcode) { 917cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler DCHECK_LT((size_t) opcode, (sizeof(oat_data_flow_attributes_) / sizeof(oat_data_flow_attributes_[0]))); 918cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler return oat_data_flow_attributes_[opcode]; 919cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler} 920cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler 921cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyleruint64_t MIRGraph::GetDataFlowAttributes(MIR* mir) { 922cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler DCHECK(mir != nullptr); 923cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler Instruction::Code opcode = mir->dalvikInsn.opcode; 924cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler return GetDataFlowAttributes(opcode); 925cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler} 926cc794c3dc5b45601da23fb0d7bc16f9b4ef04065Jean Christophe Beyler 927cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe// The path can easily surpass FS limits because of parameters etc. Use pathconf to get FS 928cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe// restrictions here. Note that a successful invocation will return an actual value. If the path 929cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe// is too long for some reason, the return will be ENAMETOOLONG. Then cut off part of the name. 930cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe// 931cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe// It's possible the path is not valid, or some other errors appear. In that case return false. 932cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampestatic bool CreateDumpFile(std::string& fname, const char* dir_prefix, NarrowDexOffset start_offset, 933cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe const char *suffix, int nr, std::string* output) { 934cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe std::string dir = StringPrintf("./%s", dir_prefix); 935cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe int64_t max_name_length = pathconf(dir.c_str(), _PC_NAME_MAX); 936cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe if (max_name_length <= 0) { 937cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe PLOG(ERROR) << "Could not get file name restrictions for " << dir; 938cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe return false; 939cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe } 940cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe 941cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe std::string name = StringPrintf("%s%x%s_%d.dot", fname.c_str(), start_offset, 942cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe suffix == nullptr ? "" : suffix, nr); 943cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe std::string fpath; 944cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe if (static_cast<int64_t>(name.size()) > max_name_length) { 945cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe std::string suffix_str = StringPrintf("_%d.dot", nr); 946cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe name = name.substr(0, static_cast<size_t>(max_name_length) - suffix_str.size()) + suffix_str; 947cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe } 948cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe // Sanity check. 949cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe DCHECK_LE(name.size(), static_cast<size_t>(max_name_length)); 950cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe 951cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe *output = StringPrintf("%s%s", dir_prefix, name.c_str()); 952cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe return true; 953cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe} 954cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe 955311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee// TODO: use a configurable base prefix, and adjust callers to supply pass name. 956311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/* Dump the CFG into a DOT graph */ 957d0a515562772d7c637160e8779c4f253ee169c3aJean Christophe Beylervoid MIRGraph::DumpCFG(const char* dir_prefix, bool all_blocks, const char *suffix) { 958311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee FILE* file; 959a8869e60d93ba9eed36a5b53553b7609f58fc05bJean Christophe Beyler static AtomicInteger cnt(0); 960a8869e60d93ba9eed36a5b53553b7609f58fc05bJean Christophe Beyler 961a8869e60d93ba9eed36a5b53553b7609f58fc05bJean Christophe Beyler // Increment counter to get a unique file number. 962a8869e60d93ba9eed36a5b53553b7609f58fc05bJean Christophe Beyler cnt++; 963cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe int nr = cnt.LoadRelaxed(); 964a8869e60d93ba9eed36a5b53553b7609f58fc05bJean Christophe Beyler 965311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee std::string fname(PrettyMethod(cu_->method_idx, *cu_->dex_file)); 966311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee ReplaceSpecialChars(fname); 967cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe std::string fpath; 968cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe if (!CreateDumpFile(fname, dir_prefix, GetBasicBlock(GetEntryBlock()->fall_through)->start_offset, 969cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe suffix, nr, &fpath)) { 970cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe LOG(ERROR) << "Could not create dump file name for " << fname; 971cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe return; 972cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe } 973cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe file = fopen(fpath.c_str(), "w"); 9742cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (file == nullptr) { 975cee97e51ed45401c274cd67bfa6216624a995f6fAndreas Gampe PLOG(ERROR) << "Could not open " << fpath << " for DumpCFG."; 976311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee return; 977311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 978311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, "digraph G {\n"); 979311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 980311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " rankdir=TB\n"); 981311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 982311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int num_blocks = all_blocks ? GetNumBlocks() : num_reachable_blocks_; 983311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int idx; 984311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 985311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (idx = 0; idx < num_blocks; idx++) { 986e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko int block_idx = all_blocks ? idx : dfs_order_[idx]; 9878512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler BasicBlock* bb = GetBasicBlock(block_idx); 9882cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (bb == nullptr) continue; 989311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (bb->block_type == kDead) continue; 990a8869e60d93ba9eed36a5b53553b7609f58fc05bJean Christophe Beyler if (bb->hidden) continue; 991311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (bb->block_type == kEntryBlock) { 992311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " entry_%d [shape=Mdiamond];\n", bb->id); 993311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } else if (bb->block_type == kExitBlock) { 994311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " exit_%d [shape=Mdiamond];\n", bb->id); 995311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } else if (bb->block_type == kDalvikByteCode) { 996311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " block%04x_%d [shape=record,label = \"{ \\\n", 997311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bb->start_offset, bb->id); 9988512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler const MIR* mir; 999311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " {block id %d\\l}%s\\\n", bb->id, 1000311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bb->first_mir_insn ? " | " : " "); 1001311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee for (mir = bb->first_mir_insn; mir; mir = mir->next) { 1002311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int opcode = mir->dalvikInsn.opcode; 1003e0951144d71a4791a5319ec507d84fce373018e0Razvan A Lupusoru fprintf(file, " {%04x %s %s %s %s %s %s %s %s %s\\l}%s\\\n", mir->offset, 1004d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell mir->ssa_rep ? GetDalvikDisassembly(mir) : 10052ab40eb3c23559205ac7b9b039bd749458e8a761Jean Christophe Beyler !MIR::DecodedInstruction::IsPseudoMirOp(opcode) ? 10062ab40eb3c23559205ac7b9b039bd749458e8a761Jean Christophe Beyler Instruction::Name(mir->dalvikInsn.opcode) : 1007d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell extended_mir_op_names_[opcode - kMirOpFirst], 1008d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell (mir->optimization_flags & MIR_IGNORE_RANGE_CHECK) != 0 ? " no_rangecheck" : " ", 1009d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell (mir->optimization_flags & MIR_IGNORE_NULL_CHECK) != 0 ? " no_nullcheck" : " ", 101060bfe7b3e8f00f0a8ef3f5d8716adfdf86b71f43Udayan Banerji (mir->optimization_flags & MIR_IGNORE_SUSPEND_CHECK) != 0 ? " no_suspendcheck" : " ", 1011b5bce7cc9f1130ab4932ba8e6917c362bf871f24Jean Christophe Beyler (mir->optimization_flags & MIR_STORE_NON_TEMPORAL) != 0 ? " non_temporal" : " ", 10121500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru (mir->optimization_flags & MIR_CALLEE) != 0 ? " inlined" : " ", 101366c6d7bdfdd535e6ecf4461bba3804f1a7794fcdVladimir Marko (mir->optimization_flags & MIR_CLASS_IS_INITIALIZED) != 0 ? " cl_inited" : " ", 101466c6d7bdfdd535e6ecf4461bba3804f1a7794fcdVladimir Marko (mir->optimization_flags & MIR_CLASS_IS_IN_DEX_CACHE) != 0 ? " cl_in_cache" : " ", 1015e0951144d71a4791a5319ec507d84fce373018e0Razvan A Lupusoru (mir->optimization_flags & MIR_IGNORE_DIV_ZERO_CHECK) != 0 ? " no_div_check" : " ", 1016d65c51a556e6649db4e18bd083c8fec37607a442Mark Mendell mir->next ? " | " : " "); 1017311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 1018311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " }\"];\n\n"); 1019311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } else if (bb->block_type == kExceptionHandling) { 1020311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee char block_name[BLOCK_NAME_LEN]; 1021311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 1022311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee GetBlockName(bb, block_name); 1023311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " %s [shape=invhouse];\n", block_name); 1024311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 1025311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 1026311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee char block_name1[BLOCK_NAME_LEN], block_name2[BLOCK_NAME_LEN]; 1027311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 10280d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (bb->taken != NullBasicBlockId) { 1029311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee GetBlockName(bb, block_name1); 10300d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee GetBlockName(GetBasicBlock(bb->taken), block_name2); 1031311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " %s:s -> %s:n [style=dotted]\n", 1032311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee block_name1, block_name2); 1033311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 10340d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (bb->fall_through != NullBasicBlockId) { 1035311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee GetBlockName(bb, block_name1); 10360d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee GetBlockName(GetBasicBlock(bb->fall_through), block_name2); 1037311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " %s:s -> %s:n\n", block_name1, block_name2); 1038311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 1039311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 10400d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (bb->successor_block_list_type != kNotUsed) { 1041311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " succ%04x_%d [shape=%s,label = \"{ \\\n", 1042311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee bb->start_offset, bb->id, 10430d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee (bb->successor_block_list_type == kCatch) ? "Mrecord" : "record"); 1044311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 1045e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko int last_succ_id = static_cast<int>(bb->successor_blocks.size() - 1u); 1046311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee int succ_id = 0; 1047e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (SuccessorBlockInfo* successor_block_info : bb->successor_blocks) { 10488512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler BasicBlock* dest_block = GetBasicBlock(successor_block_info->block); 1049311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " {<f%d> %04x: %04x\\l}%s\\\n", 1050e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko succ_id, 1051311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee successor_block_info->key, 1052311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee dest_block->start_offset, 1053e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko (succ_id != last_succ_id) ? " | " : " "); 1054e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko ++succ_id; 1055311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 1056311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " }\"];\n\n"); 1057311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 1058311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee GetBlockName(bb, block_name1); 1059311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " %s:s -> succ%04x_%d:n [style=dashed]\n", 1060311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee block_name1, bb->start_offset, bb->id); 1061311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 106225bc279080a56546b0f8a33342a853b2778eed0dRazvan A Lupusoru // Link the successor pseudo-block with all of its potential targets. 106325bc279080a56546b0f8a33342a853b2778eed0dRazvan A Lupusoru succ_id = 0; 1064e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (SuccessorBlockInfo* successor_block_info : bb->successor_blocks) { 106525bc279080a56546b0f8a33342a853b2778eed0dRazvan A Lupusoru BasicBlock* dest_block = GetBasicBlock(successor_block_info->block); 1066311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 106725bc279080a56546b0f8a33342a853b2778eed0dRazvan A Lupusoru GetBlockName(dest_block, block_name2); 106825bc279080a56546b0f8a33342a853b2778eed0dRazvan A Lupusoru fprintf(file, " succ%04x_%d:f%d:e -> %s:n\n", bb->start_offset, 106925bc279080a56546b0f8a33342a853b2778eed0dRazvan A Lupusoru bb->id, succ_id++, block_name2); 1070311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 1071311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 1072311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, "\n"); 1073311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 1074311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (cu_->verbose) { 1075311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee /* Display the dominator tree */ 1076311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee GetBlockName(bb, block_name1); 1077311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " cfg%s [label=\"%s\", shape=none];\n", 1078311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee block_name1, block_name1); 1079311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee if (bb->i_dom) { 10800d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee GetBlockName(GetBasicBlock(bb->i_dom), block_name2); 1081311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, " cfg%s:s -> cfg%s:n\n\n", block_name2, block_name1); 1082311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 1083311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 1084311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee } 1085311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fprintf(file, "}\n"); 1086311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee fclose(file); 1087311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee} 1088311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee 10893aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler/* Insert an MIR instruction to the end of a basic block. */ 1090cdacac4a8196bdc620185079ec9e886329606f3dJean Christophe Beylervoid BasicBlock::AppendMIR(MIR* mir) { 10918512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Insert it after the last MIR. 10928512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler InsertMIRListAfter(last_mir_insn, mir, mir); 10938512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 10948512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 10958512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylervoid BasicBlock::AppendMIRList(MIR* first_list_mir, MIR* last_list_mir) { 10968512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Insert it after the last MIR. 10978512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler InsertMIRListAfter(last_mir_insn, first_list_mir, last_list_mir); 10988512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 10998512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 11008512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylervoid BasicBlock::AppendMIRList(const std::vector<MIR*>& insns) { 11018512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler for (std::vector<MIR*>::const_iterator it = insns.begin(); it != insns.end(); it++) { 11028512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler MIR* new_mir = *it; 11038512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 11048512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Add a copy of each MIR. 11058512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler InsertMIRListAfter(last_mir_insn, new_mir, new_mir); 11068512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 11078512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 11088512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 11098512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler/* Insert a MIR instruction after the specified MIR. */ 11108512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylervoid BasicBlock::InsertMIRAfter(MIR* current_mir, MIR* new_mir) { 11118512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler InsertMIRListAfter(current_mir, new_mir, new_mir); 11128512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 11138512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 11148512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylervoid BasicBlock::InsertMIRListAfter(MIR* insert_after, MIR* first_list_mir, MIR* last_list_mir) { 11158512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // If no MIR, we are done. 11168512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (first_list_mir == nullptr || last_list_mir == nullptr) { 11178512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return; 11188512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 11198512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 11208512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // If insert_after is null, assume BB is empty. 11218512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (insert_after == nullptr) { 11228512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler first_mir_insn = first_list_mir; 11238512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_mir_insn = last_list_mir; 11248512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_list_mir->next = nullptr; 11251fd3346740dfb7f47be9922312b68a4227fada96buzbee } else { 11268512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler MIR* after_list = insert_after->next; 11278512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler insert_after->next = first_list_mir; 11288512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_list_mir->next = after_list; 11298512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (after_list == nullptr) { 11308512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_mir_insn = last_list_mir; 11318512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 11321fd3346740dfb7f47be9922312b68a4227fada96buzbee } 11333aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 11348512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Set this BB to be the basic block of the MIRs. 11358512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler MIR* last = last_list_mir->next; 11368512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler for (MIR* mir = first_list_mir; mir != last; mir = mir->next) { 11378512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler mir->bb = id; 11388512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 11391fd3346740dfb7f47be9922312b68a4227fada96buzbee} 11401fd3346740dfb7f47be9922312b68a4227fada96buzbee 11413aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler/* Insert an MIR instruction to the head of a basic block. */ 1142cdacac4a8196bdc620185079ec9e886329606f3dJean Christophe Beylervoid BasicBlock::PrependMIR(MIR* mir) { 11438512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler InsertMIRListBefore(first_mir_insn, mir, mir); 11448512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 11453aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 11468512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylervoid BasicBlock::PrependMIRList(MIR* first_list_mir, MIR* last_list_mir) { 11478512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Insert it before the first MIR. 11488512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler InsertMIRListBefore(first_mir_insn, first_list_mir, last_list_mir); 11491fd3346740dfb7f47be9922312b68a4227fada96buzbee} 11501fd3346740dfb7f47be9922312b68a4227fada96buzbee 11518512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylervoid BasicBlock::PrependMIRList(const std::vector<MIR*>& to_add) { 11528512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler for (std::vector<MIR*>::const_iterator it = to_add.begin(); it != to_add.end(); it++) { 11538512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler MIR* mir = *it; 11541fd3346740dfb7f47be9922312b68a4227fada96buzbee 11558512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler InsertMIRListBefore(first_mir_insn, mir, mir); 11561fd3346740dfb7f47be9922312b68a4227fada96buzbee } 11578512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 11583aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 11598512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler/* Insert a MIR instruction before the specified MIR. */ 11608512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylervoid BasicBlock::InsertMIRBefore(MIR* current_mir, MIR* new_mir) { 11618512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Insert as a single element list. 11628512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return InsertMIRListBefore(current_mir, new_mir, new_mir); 11633aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler} 11643aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 11653aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe BeylerMIR* BasicBlock::FindPreviousMIR(MIR* mir) { 11663aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler MIR* current = first_mir_insn; 11673aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 11683aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler while (current != nullptr) { 11693aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler MIR* next = current->next; 11703aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 11713aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler if (next == mir) { 11723aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler return current; 11733aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler } 11743aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 11753aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler current = next; 11763aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler } 11773aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 11783aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler return nullptr; 11793aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler} 11803aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 11818512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylervoid BasicBlock::InsertMIRListBefore(MIR* insert_before, MIR* first_list_mir, MIR* last_list_mir) { 11828512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // If no MIR, we are done. 11838512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (first_list_mir == nullptr || last_list_mir == nullptr) { 11848512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return; 11858512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 11868512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 11878512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // If insert_before is null, assume BB is empty. 11888512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (insert_before == nullptr) { 11898512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler first_mir_insn = first_list_mir; 11908512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_mir_insn = last_list_mir; 11918512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_list_mir->next = nullptr; 11928512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } else { 11938512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (first_mir_insn == insert_before) { 11948512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_list_mir->next = first_mir_insn; 11958512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler first_mir_insn = first_list_mir; 11968512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } else { 11978512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Find the preceding MIR. 11988512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler MIR* before_list = FindPreviousMIR(insert_before); 11998512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler DCHECK(before_list != nullptr); 12008512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler before_list->next = first_list_mir; 12018512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_list_mir->next = insert_before; 12028512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 12038512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 12048512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 12058512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Set this BB to be the basic block of the MIRs. 12068512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler for (MIR* mir = first_list_mir; mir != last_list_mir->next; mir = mir->next) { 12078512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler mir->bb = id; 12083aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler } 12098512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 12108512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 12118512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylerbool BasicBlock::RemoveMIR(MIR* mir) { 12128512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Remove as a single element list. 12138512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return RemoveMIRList(mir, mir); 12148512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 12158512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 12168512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylerbool BasicBlock::RemoveMIRList(MIR* first_list_mir, MIR* last_list_mir) { 12178512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (first_list_mir == nullptr) { 12188512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return false; 12198512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 12208512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 12218512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Try to find the MIR. 12228512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler MIR* before_list = nullptr; 12238512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler MIR* after_list = nullptr; 12243aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 12258512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // If we are removing from the beginning of the MIR list. 12268512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (first_mir_insn == first_list_mir) { 12278512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler before_list = nullptr; 12288512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } else { 12298512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler before_list = FindPreviousMIR(first_list_mir); 12308512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (before_list == nullptr) { 12318512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // We did not find the mir. 12328512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return false; 12338512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 12348512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 12358512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 1236a4307aca310aac0ac62dcb5435daa02b1f950558Jean Christophe Beyler // Remove the BB information and also find the after_list. 1237590c6a4ded1deb378baa253c86070d8eeffdc820Chao-ying Fu for (MIR* mir = first_list_mir; mir != last_list_mir->next; mir = mir->next) { 12388512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler mir->bb = NullBasicBlockId; 12398512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 12408512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 12418512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler after_list = last_list_mir->next; 12428512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 1243a4307aca310aac0ac62dcb5435daa02b1f950558Jean Christophe Beyler // If there is nothing before the list, after_list is the first_mir. 12448512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (before_list == nullptr) { 12458512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler first_mir_insn = after_list; 1246a4307aca310aac0ac62dcb5435daa02b1f950558Jean Christophe Beyler } else { 1247a4307aca310aac0ac62dcb5435daa02b1f950558Jean Christophe Beyler before_list->next = after_list; 12488512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 12493aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 1250a4307aca310aac0ac62dcb5435daa02b1f950558Jean Christophe Beyler // If there is nothing after the list, before_list is last_mir. 12518512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (after_list == nullptr) { 12528512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_mir_insn = before_list; 12533aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler } 12548512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 12558512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return true; 12561fd3346740dfb7f47be9922312b68a4227fada96buzbee} 12571fd3346740dfb7f47be9922312b68a4227fada96buzbee 125826e7d454b9924f3673b075b05e4c604ad658a062Vladimir MarkoMIR* BasicBlock::GetFirstNonPhiInsn() { 125926e7d454b9924f3673b075b05e4c604ad658a062Vladimir Marko MIR* mir = first_mir_insn; 126026e7d454b9924f3673b075b05e4c604ad658a062Vladimir Marko while (mir != nullptr && static_cast<int>(mir->dalvikInsn.opcode) == kMirOpPhi) { 126126e7d454b9924f3673b075b05e4c604ad658a062Vladimir Marko mir = mir->next; 126226e7d454b9924f3673b075b05e4c604ad658a062Vladimir Marko } 126326e7d454b9924f3673b075b05e4c604ad658a062Vladimir Marko return mir; 126426e7d454b9924f3673b075b05e4c604ad658a062Vladimir Marko} 126526e7d454b9924f3673b075b05e4c604ad658a062Vladimir Marko 1266cdacac4a8196bdc620185079ec9e886329606f3dJean Christophe BeylerMIR* BasicBlock::GetNextUnconditionalMir(MIRGraph* mir_graph, MIR* current) { 12673bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru MIR* next_mir = nullptr; 12683bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru 12693bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru if (current != nullptr) { 12703bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru next_mir = current->next; 12713bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru } 12723bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru 12733bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru if (next_mir == nullptr) { 12743bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru // Only look for next MIR that follows unconditionally. 1275cdacac4a8196bdc620185079ec9e886329606f3dJean Christophe Beyler if ((taken == NullBasicBlockId) && (fall_through != NullBasicBlockId)) { 1276cdacac4a8196bdc620185079ec9e886329606f3dJean Christophe Beyler next_mir = mir_graph->GetBasicBlock(fall_through)->first_mir_insn; 12773bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru } 12783bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru } 12793bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru 12803bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru return next_mir; 12813bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru} 12823bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru 12831500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusorustatic void FillTypeSizeString(uint32_t type_size, std::string* decoded_mir) { 12841500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru DCHECK(decoded_mir != nullptr); 12851500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru OpSize type = static_cast<OpSize>(type_size >> 16); 12861500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru uint16_t vect_size = (type_size & 0xFFFF); 12871500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru 12881500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru // Now print the type and vector size. 12891500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru std::stringstream ss; 12901500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru ss << " (type:"; 12911500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru ss << type; 12921500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru ss << " vectsize:"; 12931500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru ss << vect_size; 12941500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru ss << ")"; 12951500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru 12961500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(ss.str()); 12971500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru} 12981500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru 12991500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoruvoid MIRGraph::DisassembleExtendedInstr(const MIR* mir, std::string* decoded_mir) { 13001500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru DCHECK(decoded_mir != nullptr); 13011500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru int opcode = mir->dalvikInsn.opcode; 13021500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru SSARepresentation* ssa_rep = mir->ssa_rep; 13031500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru int defs = (ssa_rep != nullptr) ? ssa_rep->num_defs : 0; 13041500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru int uses = (ssa_rep != nullptr) ? ssa_rep->num_uses : 0; 13051500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru 1306f41b92c7a2fcdd411b9edd7070e4729ea18e0ba6Vladimir if (opcode < kMirOpFirst) { 1307f41b92c7a2fcdd411b9edd7070e4729ea18e0ba6Vladimir return; // It is not an extended instruction. 1308f41b92c7a2fcdd411b9edd7070e4729ea18e0ba6Vladimir } 1309f41b92c7a2fcdd411b9edd7070e4729ea18e0ba6Vladimir 13101500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(extended_mir_op_names_[opcode - kMirOpFirst]); 13111500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru 13121500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru switch (opcode) { 13131500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPhi: { 13141500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (defs > 0 && uses > 0) { 13151500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru BasicBlockId* incoming = mir->meta.phi_incoming; 13161500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" %s = (%s", 13171500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru GetSSANameWithConst(ssa_rep->defs[0], true).c_str(), 13181500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru GetSSANameWithConst(ssa_rep->uses[0], true).c_str())); 13191500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(":%d", incoming[0])); 13201500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru for (int i = 1; i < uses; i++) { 13211500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(", %s:%d", GetSSANameWithConst(ssa_rep->uses[i], true).c_str(), incoming[i])); 13221500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 13231500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(")"); 13241500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 13251500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13261500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 13271500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpCopy: 13281500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (ssa_rep != nullptr) { 13291500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(" "); 13301500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[0], false)); 13311500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (defs > 1) { 13321500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(", "); 13331500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[1], false)); 13341500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 13351500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(" = "); 13361500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->uses[0], false)); 13371500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (uses > 1) { 13381500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(", "); 13391500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->uses[1], false)); 13401500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 13411500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } else { 13421500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" v%d = v%d", mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 13431500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 13441500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13451500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpFusedCmplFloat: 13461500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpFusedCmpgFloat: 13471500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpFusedCmplDouble: 13481500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpFusedCmpgDouble: 13491500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpFusedCmpLong: 13501500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (ssa_rep != nullptr) { 13511500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(" "); 13521500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->uses[0], false)); 13531500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru for (int i = 1; i < uses; i++) { 13541500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(", "); 13551500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->uses[i], false)); 13561500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 13571500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } else { 13581500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" v%d, v%d", mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 13591500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 13601500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13611500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpMoveVector: 13621500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 13631500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 13641500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13651500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedAddition: 13661500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d + vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 13671500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 13681500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13691500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedMultiply: 13701500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d * vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 13711500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 13721500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13731500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedSubtract: 13741500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d - vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 13751500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 13761500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13771500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedAnd: 13781500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d & vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 13791500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 13801500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13811500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedOr: 13821500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d \\| vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 13831500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 13841500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13851500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedXor: 13861500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d ^ vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 13871500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 13881500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13891500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedShiftLeft: 13901500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d \\<\\< %d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 13911500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 13921500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13931500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedUnsignedShiftRight: 13941500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d \\>\\>\\> %d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 13951500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 13961500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 13971500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedSignedShiftRight: 13981500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = vect%d \\>\\> %d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 13991500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 14001500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 14011500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpConstVector: 14021500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = %x, %x, %x, %x", mir->dalvikInsn.vA, mir->dalvikInsn.arg[0], 14031500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru mir->dalvikInsn.arg[1], mir->dalvikInsn.arg[2], mir->dalvikInsn.arg[3])); 14041500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 14051500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedSet: 14061500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (ssa_rep != nullptr) { 14071500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = %s", mir->dalvikInsn.vA, 14081500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru GetSSANameWithConst(ssa_rep->uses[0], false).c_str())); 14091500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (uses > 1) { 14101500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(", "); 14111500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->uses[1], false)); 14121500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 14131500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } else { 14141500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d = v%d", mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 14151500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 14161500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 14171500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 14181500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedAddReduce: 14191500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (ssa_rep != nullptr) { 14201500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(" "); 14211500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[0], false)); 14221500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (defs > 1) { 14231500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(", "); 14241500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[1], false)); 14251500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 14261500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" = vect%d + %s", mir->dalvikInsn.vB, 14271500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru GetSSANameWithConst(ssa_rep->uses[0], false).c_str())); 14281500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (uses > 1) { 14291500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(", "); 14301500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->uses[1], false)); 14311500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 14321500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } else { 14331500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf("v%d = vect%d + v%d", mir->dalvikInsn.vA, mir->dalvikInsn.vB, mir->dalvikInsn.vA)); 14341500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 14351500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 14361500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 14371500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpPackedReduce: 14381500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (ssa_rep != nullptr) { 14391500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(" "); 14401500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[0], false)); 14411500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (defs > 1) { 14421500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(", "); 14431500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[1], false)); 14441500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 1445b72c723bfb21e05cb9b0a7999db805df93fcaee8Razvan A Lupusoru decoded_mir->append(StringPrintf(" = vect%d (extr_idx:%d)", mir->dalvikInsn.vB, mir->dalvikInsn.arg[0])); 14461500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } else { 1447b72c723bfb21e05cb9b0a7999db805df93fcaee8Razvan A Lupusoru decoded_mir->append(StringPrintf(" v%d = vect%d (extr_idx:%d)", mir->dalvikInsn.vA, 1448b72c723bfb21e05cb9b0a7999db805df93fcaee8Razvan A Lupusoru mir->dalvikInsn.vB, mir->dalvikInsn.arg[0])); 14491500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 14501500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir); 14511500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 14521500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpReserveVectorRegisters: 14531500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpReturnVectorRegisters: 14541500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(StringPrintf(" vect%d - vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vB)); 14551500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 14561500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru case kMirOpMemBarrier: { 14571500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(" type:"); 14581500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru std::stringstream ss; 14591500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru ss << static_cast<MemBarrierKind>(mir->dalvikInsn.vA); 14601500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru decoded_mir->append(ss.str()); 14611500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 14621500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 1463b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A case kMirOpPackedArrayGet: 1464b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A case kMirOpPackedArrayPut: 1465b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A decoded_mir->append(StringPrintf(" vect%d", mir->dalvikInsn.vA)); 1466b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A if (ssa_rep != nullptr) { 1467b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A decoded_mir->append(StringPrintf(", %s[%s]", 1468b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A GetSSANameWithConst(ssa_rep->uses[0], false).c_str(), 1469b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A GetSSANameWithConst(ssa_rep->uses[1], false).c_str())); 1470b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A } else { 1471b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A decoded_mir->append(StringPrintf(", v%d[v%d]", mir->dalvikInsn.vB, mir->dalvikInsn.vC)); 1472b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A } 1473b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A FillTypeSizeString(mir->dalvikInsn.arg[0], decoded_mir); 1474b3a84e2f308b3ed7d17b8e96fc7adfcac36ebe77Lupusoru, Razvan A break; 1475a262f7707330dccfb50af6345813083182b61043Ningsheng Jian case kMirOpMaddInt: 1476a262f7707330dccfb50af6345813083182b61043Ningsheng Jian case kMirOpMsubInt: 1477a262f7707330dccfb50af6345813083182b61043Ningsheng Jian case kMirOpMaddLong: 1478a262f7707330dccfb50af6345813083182b61043Ningsheng Jian case kMirOpMsubLong: 1479a262f7707330dccfb50af6345813083182b61043Ningsheng Jian if (ssa_rep != nullptr) { 1480a262f7707330dccfb50af6345813083182b61043Ningsheng Jian decoded_mir->append(" "); 1481a262f7707330dccfb50af6345813083182b61043Ningsheng Jian decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[0], false)); 1482a262f7707330dccfb50af6345813083182b61043Ningsheng Jian if (defs > 1) { 1483a262f7707330dccfb50af6345813083182b61043Ningsheng Jian decoded_mir->append(", "); 1484a262f7707330dccfb50af6345813083182b61043Ningsheng Jian decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[1], false)); 1485a262f7707330dccfb50af6345813083182b61043Ningsheng Jian } 1486a262f7707330dccfb50af6345813083182b61043Ningsheng Jian for (int i = 0; i < uses; i++) { 1487a262f7707330dccfb50af6345813083182b61043Ningsheng Jian decoded_mir->append(", "); 1488a262f7707330dccfb50af6345813083182b61043Ningsheng Jian decoded_mir->append(GetSSANameWithConst(ssa_rep->uses[i], false)); 1489a262f7707330dccfb50af6345813083182b61043Ningsheng Jian } 1490a262f7707330dccfb50af6345813083182b61043Ningsheng Jian } else { 1491a262f7707330dccfb50af6345813083182b61043Ningsheng Jian decoded_mir->append(StringPrintf(" v%d, v%d, v%d, v%d", 1492a262f7707330dccfb50af6345813083182b61043Ningsheng Jian mir->dalvikInsn.vA, mir->dalvikInsn.vB, 1493a262f7707330dccfb50af6345813083182b61043Ningsheng Jian mir->dalvikInsn.vC, mir->dalvikInsn.arg[0])); 1494a262f7707330dccfb50af6345813083182b61043Ningsheng Jian } 1495a262f7707330dccfb50af6345813083182b61043Ningsheng Jian break; 14961500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru default: 14971500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 14981500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 14991500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru} 15001500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru 15012ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromchar* MIRGraph::GetDalvikDisassembly(const MIR* mir) { 150229a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers MIR::DecodedInstruction insn = mir->dalvikInsn; 15031fd3346740dfb7f47be9922312b68a4227fada96buzbee std::string str; 15041fd3346740dfb7f47be9922312b68a4227fada96buzbee int flags = 0; 15051fd3346740dfb7f47be9922312b68a4227fada96buzbee int opcode = insn.opcode; 15061fd3346740dfb7f47be9922312b68a4227fada96buzbee char* ret; 15071fd3346740dfb7f47be9922312b68a4227fada96buzbee bool nop = false; 15081fd3346740dfb7f47be9922312b68a4227fada96buzbee SSARepresentation* ssa_rep = mir->ssa_rep; 15098512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler Instruction::Format dalvik_format = Instruction::k10x; // Default to no-operand format. 15101fd3346740dfb7f47be9922312b68a4227fada96buzbee 15111500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru // Handle special cases that recover the original dalvik instruction. 1512f80552b7e5f627a5dd07af017b7d65dec010ca48Vladimir Marko if (opcode == kMirOpCheck) { 15131fd3346740dfb7f47be9922312b68a4227fada96buzbee str.append(extended_mir_op_names_[opcode - kMirOpFirst]); 15141fd3346740dfb7f47be9922312b68a4227fada96buzbee str.append(": "); 15158512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Recover the original Dex instruction. 15161fd3346740dfb7f47be9922312b68a4227fada96buzbee insn = mir->meta.throw_insn->dalvikInsn; 15171fd3346740dfb7f47be9922312b68a4227fada96buzbee ssa_rep = mir->meta.throw_insn->ssa_rep; 15181fd3346740dfb7f47be9922312b68a4227fada96buzbee opcode = insn.opcode; 15191fd3346740dfb7f47be9922312b68a4227fada96buzbee } else if (opcode == kMirOpNop) { 15201fd3346740dfb7f47be9922312b68a4227fada96buzbee str.append("["); 1521750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru if (mir->offset < current_code_item_->insns_size_in_code_units_) { 1522750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru // Recover original opcode. 1523750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru insn.opcode = Instruction::At(current_code_item_->insns_ + mir->offset)->Opcode(); 1524750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru opcode = insn.opcode; 1525750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru } 15261fd3346740dfb7f47be9922312b68a4227fada96buzbee nop = true; 15271fd3346740dfb7f47be9922312b68a4227fada96buzbee } 15282cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier int defs = (ssa_rep != nullptr) ? ssa_rep->num_defs : 0; 15292cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier int uses = (ssa_rep != nullptr) ? ssa_rep->num_uses : 0; 15301fd3346740dfb7f47be9922312b68a4227fada96buzbee 15312ab40eb3c23559205ac7b9b039bd749458e8a761Jean Christophe Beyler if (MIR::DecodedInstruction::IsPseudoMirOp(opcode)) { 15321500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru // Note that this does not check the MIR's opcode in all cases. In cases where it 15331500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru // recovered dalvik instruction, it uses opcode of that instead of the extended one. 15341500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru DisassembleExtendedInstr(mir, &str); 15351fd3346740dfb7f47be9922312b68a4227fada96buzbee } else { 15361fd3346740dfb7f47be9922312b68a4227fada96buzbee dalvik_format = Instruction::FormatOf(insn.opcode); 1537fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler flags = insn.FlagsOf(); 15381fd3346740dfb7f47be9922312b68a4227fada96buzbee str.append(Instruction::Name(insn.opcode)); 15391fd3346740dfb7f47be9922312b68a4227fada96buzbee 15408512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // For invokes-style formats, treat wide regs as a pair of singles. 15411fd3346740dfb7f47be9922312b68a4227fada96buzbee bool show_singles = ((dalvik_format == Instruction::k35c) || 15421fd3346740dfb7f47be9922312b68a4227fada96buzbee (dalvik_format == Instruction::k3rc)); 15431fd3346740dfb7f47be9922312b68a4227fada96buzbee if (defs != 0) { 15441500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(" "); 15451500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(GetSSANameWithConst(ssa_rep->defs[0], false)); 15461500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (defs > 1) { 15471500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(", "); 15481500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(GetSSANameWithConst(ssa_rep->defs[1], false)); 15491500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 15501fd3346740dfb7f47be9922312b68a4227fada96buzbee if (uses != 0) { 15511fd3346740dfb7f47be9922312b68a4227fada96buzbee str.append(", "); 15521fd3346740dfb7f47be9922312b68a4227fada96buzbee } 15531fd3346740dfb7f47be9922312b68a4227fada96buzbee } 15541fd3346740dfb7f47be9922312b68a4227fada96buzbee for (int i = 0; i < uses; i++) { 15551500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(" "); 15561500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(GetSSANameWithConst(ssa_rep->uses[i], show_singles)); 15572cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (!show_singles && (reg_location_ != nullptr) && reg_location_[i].wide) { 15581fd3346740dfb7f47be9922312b68a4227fada96buzbee // For the listing, skip the high sreg. 15591fd3346740dfb7f47be9922312b68a4227fada96buzbee i++; 15601fd3346740dfb7f47be9922312b68a4227fada96buzbee } 15611500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (i != (uses - 1)) { 15621fd3346740dfb7f47be9922312b68a4227fada96buzbee str.append(","); 15631fd3346740dfb7f47be9922312b68a4227fada96buzbee } 15641fd3346740dfb7f47be9922312b68a4227fada96buzbee } 15651500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru 15661fd3346740dfb7f47be9922312b68a4227fada96buzbee switch (dalvik_format) { 15678512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler case Instruction::k11n: // Add one immediate from vB. 15681fd3346740dfb7f47be9922312b68a4227fada96buzbee case Instruction::k21s: 15691fd3346740dfb7f47be9922312b68a4227fada96buzbee case Instruction::k31i: 15701fd3346740dfb7f47be9922312b68a4227fada96buzbee case Instruction::k21h: 15711500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(StringPrintf(", #0x%x", insn.vB)); 15721fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 15738512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler case Instruction::k51l: // Add one wide immediate. 157423b03b5b5fdaa517eda3b8b358752672cf6046b1Ian Rogers str.append(StringPrintf(", #%" PRId64, insn.vB_wide)); 15751fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 15768512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler case Instruction::k21c: // One register, one string/type/method index. 15771fd3346740dfb7f47be9922312b68a4227fada96buzbee case Instruction::k31c: 15781500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(StringPrintf(", index #0x%x", insn.vB)); 15791fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 15808512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler case Instruction::k22c: // Two registers, one string/type/method index. 15811500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(StringPrintf(", index #0x%x", insn.vC)); 15821fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 15838512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler case Instruction::k22s: // Add one immediate from vC. 15841fd3346740dfb7f47be9922312b68a4227fada96buzbee case Instruction::k22b: 15851500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(StringPrintf(", #0x%x", insn.vC)); 15861fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 15871500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru default: 15888512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Nothing left to print. 15891500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 159002c8cc6d1312a2b55533f02f6369dc7c94672f90Brian Carlstrom } 15911500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru 15920f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov if ((flags & Instruction::kBranch) != 0) { 15930f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov // For branches, decode the instructions to print out the branch targets. 15940f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov int offset = 0; 15950f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov switch (dalvik_format) { 15960f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov case Instruction::k21t: 15970f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov offset = insn.vB; 15980f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov break; 15990f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov case Instruction::k22t: 16000f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov offset = insn.vC; 16010f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov break; 16020f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov case Instruction::k10t: 16030f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov case Instruction::k20t: 16040f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov case Instruction::k30t: 16050f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov offset = insn.vA; 16060f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov break; 16070f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov default: 16080f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov LOG(FATAL) << "Unexpected branch format " << dalvik_format << " from " << insn.opcode; 16091500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru break; 16100f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov } 16111500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append(StringPrintf(", 0x%x (%c%x)", mir->offset + offset, 16120f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov offset > 0 ? '+' : '-', offset > 0 ? offset : -offset)); 16130f3e4989b055bfa0bad3e4fad2f4d1a8b5a09901Serguei Katkov } 16141500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru 16151500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (nop) { 16161500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru str.append("]--optimized away"); 16171500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 16181fd3346740dfb7f47be9922312b68a4227fada96buzbee } 16191fd3346740dfb7f47be9922312b68a4227fada96buzbee int length = str.length() + 1; 1620e4fcc5ba2284c201c022b52d27f7a1201d696324Vladimir Marko ret = arena_->AllocArray<char>(length, kArenaAllocDFInfo); 16211fd3346740dfb7f47be9922312b68a4227fada96buzbee strncpy(ret, str.c_str(), length); 16221fd3346740dfb7f47be9922312b68a4227fada96buzbee return ret; 16231fd3346740dfb7f47be9922312b68a4227fada96buzbee} 16241fd3346740dfb7f47be9922312b68a4227fada96buzbee 16251fd3346740dfb7f47be9922312b68a4227fada96buzbee/* Turn method name into a legal Linux file name */ 16262ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MIRGraph::ReplaceSpecialChars(std::string& str) { 16279b7085a4e7c40e7fa01932ea1647a4a33ac1c585Brian Carlstrom static const struct { const char before; const char after; } match[] = { 16289b7085a4e7c40e7fa01932ea1647a4a33ac1c585Brian Carlstrom {'/', '-'}, {';', '#'}, {' ', '#'}, {'$', '+'}, 16299b7085a4e7c40e7fa01932ea1647a4a33ac1c585Brian Carlstrom {'(', '@'}, {')', '@'}, {'<', '='}, {'>', '='} 16309b7085a4e7c40e7fa01932ea1647a4a33ac1c585Brian Carlstrom }; 16311fd3346740dfb7f47be9922312b68a4227fada96buzbee for (unsigned int i = 0; i < sizeof(match)/sizeof(match[0]); i++) { 16321fd3346740dfb7f47be9922312b68a4227fada96buzbee std::replace(str.begin(), str.end(), match[i].before, match[i].after); 16331fd3346740dfb7f47be9922312b68a4227fada96buzbee } 16341fd3346740dfb7f47be9922312b68a4227fada96buzbee} 16351fd3346740dfb7f47be9922312b68a4227fada96buzbee 16362ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromstd::string MIRGraph::GetSSAName(int ssa_reg) { 1637c7399c82c27f85a2df2653e1eb8c0b60f2cfd934Andreas Gampe // TODO: This value is needed for debugging. Currently, we compute this and then copy to the 1638c7399c82c27f85a2df2653e1eb8c0b60f2cfd934Andreas Gampe // arena. We should be smarter and just place straight into the arena, or compute the 163939ebcb800aabedd0ffa6aa4aeac8aa4194c66e61Ian Rogers // value more lazily. 16401500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru int vreg = SRegToVReg(ssa_reg); 16411500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (vreg >= static_cast<int>(GetFirstTempVR())) { 16421500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru return StringPrintf("t%d_%d", SRegToVReg(ssa_reg), GetSSASubscript(ssa_reg)); 16431500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } else { 16441500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru return StringPrintf("v%d_%d", SRegToVReg(ssa_reg), GetSSASubscript(ssa_reg)); 16451500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 16461fd3346740dfb7f47be9922312b68a4227fada96buzbee} 16471fd3346740dfb7f47be9922312b68a4227fada96buzbee 16481fd3346740dfb7f47be9922312b68a4227fada96buzbee// Similar to GetSSAName, but if ssa name represents an immediate show that as well. 16492ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromstd::string MIRGraph::GetSSANameWithConst(int ssa_reg, bool singles_only) { 16502cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (reg_location_ == nullptr) { 16518512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Pre-SSA - just use the standard name. 16521fd3346740dfb7f47be9922312b68a4227fada96buzbee return GetSSAName(ssa_reg); 16531fd3346740dfb7f47be9922312b68a4227fada96buzbee } 16541fd3346740dfb7f47be9922312b68a4227fada96buzbee if (IsConst(reg_location_[ssa_reg])) { 16559944b3b792103cb72df1953b5502ced9bf128305Mark Mendell if (!singles_only && reg_location_[ssa_reg].wide && 16569944b3b792103cb72df1953b5502ced9bf128305Mark Mendell !reg_location_[ssa_reg].high_word) { 165723b03b5b5fdaa517eda3b8b358752672cf6046b1Ian Rogers return StringPrintf("v%d_%d#0x%" PRIx64, SRegToVReg(ssa_reg), GetSSASubscript(ssa_reg), 16581fd3346740dfb7f47be9922312b68a4227fada96buzbee ConstantValueWide(reg_location_[ssa_reg])); 16591fd3346740dfb7f47be9922312b68a4227fada96buzbee } else { 1660b1eba213afaf7fa6445de863ddc9680ab99762eaBrian Carlstrom return StringPrintf("v%d_%d#0x%x", SRegToVReg(ssa_reg), GetSSASubscript(ssa_reg), 16611fd3346740dfb7f47be9922312b68a4227fada96buzbee ConstantValue(reg_location_[ssa_reg])); 16621fd3346740dfb7f47be9922312b68a4227fada96buzbee } 16631fd3346740dfb7f47be9922312b68a4227fada96buzbee } else { 16641500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru int vreg = SRegToVReg(ssa_reg); 16651500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru if (vreg >= static_cast<int>(GetFirstTempVR())) { 16661500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru return StringPrintf("t%d_%d", SRegToVReg(ssa_reg), GetSSASubscript(ssa_reg)); 16671500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } else { 16681500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru return StringPrintf("v%d_%d", SRegToVReg(ssa_reg), GetSSASubscript(ssa_reg)); 16691500e6fe209223f920cfbe6857dc4e2f0e0fc9caRazvan A Lupusoru } 16701fd3346740dfb7f47be9922312b68a4227fada96buzbee } 16711fd3346740dfb7f47be9922312b68a4227fada96buzbee} 16721fd3346740dfb7f47be9922312b68a4227fada96buzbee 16732ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MIRGraph::GetBlockName(BasicBlock* bb, char* name) { 16741fd3346740dfb7f47be9922312b68a4227fada96buzbee switch (bb->block_type) { 16751fd3346740dfb7f47be9922312b68a4227fada96buzbee case kEntryBlock: 16761fd3346740dfb7f47be9922312b68a4227fada96buzbee snprintf(name, BLOCK_NAME_LEN, "entry_%d", bb->id); 16771fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 16781fd3346740dfb7f47be9922312b68a4227fada96buzbee case kExitBlock: 16791fd3346740dfb7f47be9922312b68a4227fada96buzbee snprintf(name, BLOCK_NAME_LEN, "exit_%d", bb->id); 16801fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 16811fd3346740dfb7f47be9922312b68a4227fada96buzbee case kDalvikByteCode: 16821fd3346740dfb7f47be9922312b68a4227fada96buzbee snprintf(name, BLOCK_NAME_LEN, "block%04x_%d", bb->start_offset, bb->id); 16831fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 16841fd3346740dfb7f47be9922312b68a4227fada96buzbee case kExceptionHandling: 16851fd3346740dfb7f47be9922312b68a4227fada96buzbee snprintf(name, BLOCK_NAME_LEN, "exception%04x_%d", bb->start_offset, 16861fd3346740dfb7f47be9922312b68a4227fada96buzbee bb->id); 16871fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 16881fd3346740dfb7f47be9922312b68a4227fada96buzbee default: 16891fd3346740dfb7f47be9922312b68a4227fada96buzbee snprintf(name, BLOCK_NAME_LEN, "_%d", bb->id); 16901fd3346740dfb7f47be9922312b68a4227fada96buzbee break; 16911fd3346740dfb7f47be9922312b68a4227fada96buzbee } 16921fd3346740dfb7f47be9922312b68a4227fada96buzbee} 16931fd3346740dfb7f47be9922312b68a4227fada96buzbee 1694717a3e447c6f7a922cf9c3efe522747a187a045dSerguei Katkovconst char* MIRGraph::GetShortyFromMethodReference(const MethodReference& target_method) { 1695717a3e447c6f7a922cf9c3efe522747a187a045dSerguei Katkov const DexFile::MethodId& method_id = 1696717a3e447c6f7a922cf9c3efe522747a187a045dSerguei Katkov target_method.dex_file->GetMethodId(target_method.dex_method_index); 1697717a3e447c6f7a922cf9c3efe522747a187a045dSerguei Katkov return target_method.dex_file->GetShorty(method_id.proto_idx_); 1698717a3e447c6f7a922cf9c3efe522747a187a045dSerguei Katkov} 1699717a3e447c6f7a922cf9c3efe522747a187a045dSerguei Katkov 17001fd3346740dfb7f47be9922312b68a4227fada96buzbee/* Debug Utility - dump a compilation unit */ 17012ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstromvoid MIRGraph::DumpMIRGraph() { 17021fd3346740dfb7f47be9922312b68a4227fada96buzbee const char* block_type_names[] = { 170317189ac098b2f156713db1821b49db7b2f018bbebuzbee "Null Block", 17041fd3346740dfb7f47be9922312b68a4227fada96buzbee "Entry Block", 17051fd3346740dfb7f47be9922312b68a4227fada96buzbee "Code Block", 17061fd3346740dfb7f47be9922312b68a4227fada96buzbee "Exit Block", 17071fd3346740dfb7f47be9922312b68a4227fada96buzbee "Exception Handling", 17081fd3346740dfb7f47be9922312b68a4227fada96buzbee "Catch Block" 17091fd3346740dfb7f47be9922312b68a4227fada96buzbee }; 17101fd3346740dfb7f47be9922312b68a4227fada96buzbee 17111fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << "Compiling " << PrettyMethod(cu_->method_idx, *cu_->dex_file); 17128d0d03e24325463f0060abfd05dba5598044e9b1Razvan A Lupusoru LOG(INFO) << GetInsns(0) << " insns"; 17131fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << GetNumBlocks() << " blocks in total"; 17141fd3346740dfb7f47be9922312b68a4227fada96buzbee 1715e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (BasicBlock* bb : block_list_) { 17161fd3346740dfb7f47be9922312b68a4227fada96buzbee LOG(INFO) << StringPrintf("Block %d (%s) (insn %04x - %04x%s)", 17171fd3346740dfb7f47be9922312b68a4227fada96buzbee bb->id, 17181fd3346740dfb7f47be9922312b68a4227fada96buzbee block_type_names[bb->block_type], 17191fd3346740dfb7f47be9922312b68a4227fada96buzbee bb->start_offset, 17201fd3346740dfb7f47be9922312b68a4227fada96buzbee bb->last_mir_insn ? bb->last_mir_insn->offset : bb->start_offset, 17211fd3346740dfb7f47be9922312b68a4227fada96buzbee bb->last_mir_insn ? "" : " empty"); 17220d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (bb->taken != NullBasicBlockId) { 17230d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee LOG(INFO) << " Taken branch: block " << bb->taken 17240d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee << "(0x" << std::hex << GetBasicBlock(bb->taken)->start_offset << ")"; 17251fd3346740dfb7f47be9922312b68a4227fada96buzbee } 17260d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee if (bb->fall_through != NullBasicBlockId) { 17270d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee LOG(INFO) << " Fallthrough : block " << bb->fall_through 17280d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee << " (0x" << std::hex << GetBasicBlock(bb->fall_through)->start_offset << ")"; 17291fd3346740dfb7f47be9922312b68a4227fada96buzbee } 17301fd3346740dfb7f47be9922312b68a4227fada96buzbee } 17311fd3346740dfb7f47be9922312b68a4227fada96buzbee} 17321fd3346740dfb7f47be9922312b68a4227fada96buzbee 17331fd3346740dfb7f47be9922312b68a4227fada96buzbee/* 17341fd3346740dfb7f47be9922312b68a4227fada96buzbee * Build an array of location records for the incoming arguments. 17351fd3346740dfb7f47be9922312b68a4227fada96buzbee * Note: one location record per word of arguments, with dummy 17361fd3346740dfb7f47be9922312b68a4227fada96buzbee * high-word loc for wide arguments. Also pull up any following 17371fd3346740dfb7f47be9922312b68a4227fada96buzbee * MOVE_RESULT and incorporate it into the invoke. 17381fd3346740dfb7f47be9922312b68a4227fada96buzbee */ 1739e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu ChartierCallInfo* MIRGraph::NewMemCallInfo(BasicBlock* bb, MIR* mir, InvokeType type, bool is_range) { 1740f6c4b3ba3825de1dbb3e747a68b809c6cc8eb4dbMathieu Chartier CallInfo* info = static_cast<CallInfo*>(arena_->Alloc(sizeof(CallInfo), 174183cc7ae96d4176533dd0391a1591d321b0a87f4fVladimir Marko kArenaAllocMisc)); 17421fd3346740dfb7f47be9922312b68a4227fada96buzbee MIR* move_result_mir = FindMoveResult(bb, mir); 17432cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (move_result_mir == nullptr) { 17441fd3346740dfb7f47be9922312b68a4227fada96buzbee info->result.location = kLocInvalid; 17451fd3346740dfb7f47be9922312b68a4227fada96buzbee } else { 17461fd3346740dfb7f47be9922312b68a4227fada96buzbee info->result = GetRawDest(move_result_mir); 17471fd3346740dfb7f47be9922312b68a4227fada96buzbee move_result_mir->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop); 17481fd3346740dfb7f47be9922312b68a4227fada96buzbee } 17491fd3346740dfb7f47be9922312b68a4227fada96buzbee info->num_arg_words = mir->ssa_rep->num_uses; 1750e4fcc5ba2284c201c022b52d27f7a1201d696324Vladimir Marko info->args = (info->num_arg_words == 0) ? nullptr : 1751e4fcc5ba2284c201c022b52d27f7a1201d696324Vladimir Marko arena_->AllocArray<RegLocation>(info->num_arg_words, kArenaAllocMisc); 17526ce3eba0f2e6e505ed408cdc40d213c8a512238dVladimir Marko for (size_t i = 0; i < info->num_arg_words; i++) { 17531fd3346740dfb7f47be9922312b68a4227fada96buzbee info->args[i] = GetRawSrc(mir, i); 17541fd3346740dfb7f47be9922312b68a4227fada96buzbee } 17551fd3346740dfb7f47be9922312b68a4227fada96buzbee info->opt_flags = mir->optimization_flags; 17561fd3346740dfb7f47be9922312b68a4227fada96buzbee info->type = type; 17571fd3346740dfb7f47be9922312b68a4227fada96buzbee info->is_range = is_range; 1758e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier if (IsInstructionQuickInvoke(mir->dalvikInsn.opcode)) { 1759e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier const auto& method_info = GetMethodLoweringInfo(mir); 1760e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier info->method_ref = method_info.GetTargetMethod(); 1761e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier } else { 1762e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier info->method_ref = MethodReference(GetCurrentDexCompilationUnit()->GetDexFile(), 1763e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier mir->dalvikInsn.vB); 1764e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier } 17651fd3346740dfb7f47be9922312b68a4227fada96buzbee info->index = mir->dalvikInsn.vB; 17661fd3346740dfb7f47be9922312b68a4227fada96buzbee info->offset = mir->offset; 1767f096aad9203d7c50b2f9cbe1c1215a50c265a059Vladimir Marko info->mir = mir; 17681fd3346740dfb7f47be9922312b68a4227fada96buzbee return info; 17691fd3346740dfb7f47be9922312b68a4227fada96buzbee} 17701fd3346740dfb7f47be9922312b68a4227fada96buzbee 17713aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler// Allocate a new MIR. 17723aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe BeylerMIR* MIRGraph::NewMIR() { 17733aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler MIR* mir = new (arena_) MIR(); 17743aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler return mir; 17753aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler} 17763aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 1777862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee// Allocate a new basic block. 17782ce745c06271d5223d57dbf08117b20d5b60694aBrian CarlstromBasicBlock* MIRGraph::NewMemBB(BBType block_type, int block_id) { 1779e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* bb = new (arena_) BasicBlock(block_id, block_type, arena_); 17808512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 1781862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee // TUNING: better estimate of the exit block predecessors? 1782e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko bb->predecessors.reserve((block_type == kExitBlock) ? 2048 : 2); 1783862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee block_id_map_.Put(block_id, block_id); 1784862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee return bb; 1785862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee} 17861fd3346740dfb7f47be9922312b68a4227fada96buzbee 17874e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beylervoid MIRGraph::InitializeConstantPropagation() { 17884e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beyler is_constant_v_ = new (arena_) ArenaBitVector(arena_, GetNumSSARegs(), false); 1789e4fcc5ba2284c201c022b52d27f7a1201d696324Vladimir Marko constant_values_ = arena_->AllocArray<int>(GetNumSSARegs(), kArenaAllocDFInfo); 17904e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beyler} 17914e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beyler 17924e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beylervoid MIRGraph::InitializeMethodUses() { 17938512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // The gate starts by initializing the use counts. 17944e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beyler int num_ssa_regs = GetNumSSARegs(); 1795e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko use_counts_.clear(); 1796e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko use_counts_.reserve(num_ssa_regs + 32); 1797e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko use_counts_.resize(num_ssa_regs, 0u); 1798e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko raw_use_counts_.clear(); 1799e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko raw_use_counts_.reserve(num_ssa_regs + 32); 1800e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko raw_use_counts_.resize(num_ssa_regs, 0u); 18014e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beyler} 18024e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beyler 1803a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Markovoid MIRGraph::SSATransformationStart() { 1804a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko DCHECK(temp_scoped_alloc_.get() == nullptr); 1805a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko temp_scoped_alloc_.reset(ScopedArenaAllocator::Create(&cu_->arena_stack)); 1806f585e549682a98eec12f92033e9634dc162b7df8Vladimir Marko temp_.ssa.num_vregs = GetNumOfCodeAndTempVRs(); 1807f585e549682a98eec12f92033e9634dc162b7df8Vladimir Marko temp_.ssa.work_live_vregs = new (temp_scoped_alloc_.get()) ArenaBitVector( 1808f585e549682a98eec12f92033e9634dc162b7df8Vladimir Marko temp_scoped_alloc_.get(), temp_.ssa.num_vregs, false, kBitMapRegisterV); 18094e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beyler} 18104e97c539408f47145526f0062c1c06df99146a73Jean Christophe Beyler 1811a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Markovoid MIRGraph::SSATransformationEnd() { 1812a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko // Verify the dataflow information after the pass. 1813a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko if (cu_->enable_debug & (1 << kDebugVerifyDataflow)) { 1814a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko VerifyDataflow(); 1815a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko } 1816a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko 1817f585e549682a98eec12f92033e9634dc162b7df8Vladimir Marko temp_.ssa.num_vregs = 0u; 1818f585e549682a98eec12f92033e9634dc162b7df8Vladimir Marko temp_.ssa.work_live_vregs = nullptr; 18196a8946ba3d170fee0ff06de42209be4b14e6aff3Vladimir Marko DCHECK(temp_.ssa.def_block_matrix == nullptr); 18206a8946ba3d170fee0ff06de42209be4b14e6aff3Vladimir Marko temp_.ssa.phi_node_blocks = nullptr; 1821a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko DCHECK(temp_scoped_alloc_.get() != nullptr); 1822a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko temp_scoped_alloc_.reset(); 1823c029c98cc056bc247b69160f413ee7ce9a93d8c3Johnny Qiu 1824c029c98cc056bc247b69160f413ee7ce9a93d8c3Johnny Qiu // Update the maximum number of reachable blocks. 1825c029c98cc056bc247b69160f413ee7ce9a93d8c3Johnny Qiu max_num_reachable_blocks_ = num_reachable_blocks_; 1826ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko 1827ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko // Mark MIR SSA representations as up to date. 1828ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko mir_ssa_rep_up_to_date_ = true; 1829a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko} 1830a5b8fde2d2bc3167078694fad417fddfe442a6fdVladimir Marko 1831750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusorusize_t MIRGraph::GetNumDalvikInsns() const { 1832750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru size_t cumulative_size = 0u; 1833750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru bool counted_current_item = false; 1834750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru const uint8_t size_for_null_code_item = 2u; 1835750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru 1836750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru for (auto it : m_units_) { 1837750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru const DexFile::CodeItem* code_item = it->GetCodeItem(); 1838750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru // Even if the code item is null, we still count non-zero value so that 1839750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru // each m_unit is counted as having impact. 1840750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru cumulative_size += (code_item == nullptr ? 1841750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru size_for_null_code_item : code_item->insns_size_in_code_units_); 1842750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru if (code_item == current_code_item_) { 1843750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru counted_current_item = true; 1844750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru } 1845750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru } 1846750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru 1847750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru // If the current code item was not counted yet, count it now. 1848750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru // This can happen for example in unit tests where some fields like m_units_ 1849750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru // are not initialized. 1850750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru if (counted_current_item == false) { 1851750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru cumulative_size += (current_code_item_ == nullptr ? 1852750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru size_for_null_code_item : current_code_item_->insns_size_in_code_units_); 1853750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru } 1854750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru 1855750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru return cumulative_size; 1856750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru} 1857750359753444498d509a756fa9a042e9f3c432dfRazvan A Lupusoru 185855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Markostatic BasicBlock* SelectTopologicalSortOrderFallBack( 185955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko MIRGraph* mir_graph, const ArenaBitVector* current_loop, 186055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko const ScopedArenaVector<size_t>* visited_cnt_values, ScopedArenaAllocator* allocator, 186155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ScopedArenaVector<BasicBlockId>* tmp_stack) { 186255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // No true loop head has been found but there may be true loop heads after the mess we need 186355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // to resolve. To avoid taking one of those, pick the candidate with the highest number of 186455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // reachable unvisited nodes. That candidate will surely be a part of a loop. 186555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko BasicBlock* fall_back = nullptr; 186655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko size_t fall_back_num_reachable = 0u; 186755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Reuse the same bit vector for each candidate to mark reachable unvisited blocks. 186855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ArenaBitVector candidate_reachable(allocator, mir_graph->GetNumBlocks(), false, kBitMapMisc); 186955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko AllNodesIterator iter(mir_graph); 187055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko for (BasicBlock* candidate = iter.Next(); candidate != nullptr; candidate = iter.Next()) { 187155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (candidate->hidden || // Hidden, or 187255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko candidate->visited || // already processed, or 187355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko (*visited_cnt_values)[candidate->id] == 0u || // no processed predecessors, or 187455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko (current_loop != nullptr && // outside current loop. 187555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko !current_loop->IsBitSet(candidate->id))) { 187655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko continue; 187755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 187855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko DCHECK(tmp_stack->empty()); 187955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko tmp_stack->push_back(candidate->id); 188055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko candidate_reachable.ClearAllBits(); 188155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko size_t num_reachable = 0u; 188255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko while (!tmp_stack->empty()) { 188355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko BasicBlockId current_id = tmp_stack->back(); 188455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko tmp_stack->pop_back(); 188555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko BasicBlock* current_bb = mir_graph->GetBasicBlock(current_id); 188655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko DCHECK(current_bb != nullptr); 188755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ChildBlockIterator child_iter(current_bb, mir_graph); 188855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko BasicBlock* child_bb = child_iter.Next(); 188955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko for ( ; child_bb != nullptr; child_bb = child_iter.Next()) { 189055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko DCHECK(!child_bb->hidden); 189155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (child_bb->visited || // Already processed, or 189255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko (current_loop != nullptr && // outside current loop. 189355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko !current_loop->IsBitSet(child_bb->id))) { 189455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko continue; 189555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 189655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (!candidate_reachable.IsBitSet(child_bb->id)) { 189755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko candidate_reachable.SetBit(child_bb->id); 189855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko tmp_stack->push_back(child_bb->id); 189955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko num_reachable += 1u; 190055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 190155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 190255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 190355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (fall_back_num_reachable < num_reachable) { 190455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko fall_back_num_reachable = num_reachable; 190555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko fall_back = candidate; 190655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 190755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 190855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko return fall_back; 190955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko} 191044e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 191155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko// Compute from which unvisited blocks is bb_id reachable through unvisited blocks. 191255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Markostatic void ComputeUnvisitedReachableFrom(MIRGraph* mir_graph, BasicBlockId bb_id, 191355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ArenaBitVector* reachable, 191455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ScopedArenaVector<BasicBlockId>* tmp_stack) { 191555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // NOTE: Loop heads indicated by the "visited" flag. 191655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko DCHECK(tmp_stack->empty()); 191755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko reachable->ClearAllBits(); 191855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko tmp_stack->push_back(bb_id); 191955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko while (!tmp_stack->empty()) { 192055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko BasicBlockId current_id = tmp_stack->back(); 192155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko tmp_stack->pop_back(); 192255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko BasicBlock* current_bb = mir_graph->GetBasicBlock(current_id); 192355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko DCHECK(current_bb != nullptr); 1924e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (BasicBlockId pred_id : current_bb->predecessors) { 1925e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* pred_bb = mir_graph->GetBasicBlock(pred_id); 1926e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko DCHECK(pred_bb != nullptr); 192755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (!pred_bb->visited && !reachable->IsBitSet(pred_bb->id)) { 192855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko reachable->SetBit(pred_bb->id); 192955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko tmp_stack->push_back(pred_bb->id); 193055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 193155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 193244e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler } 193355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko} 193444e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 193555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Markovoid MIRGraph::ComputeTopologicalSortOrder() { 1936622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko ScopedArenaAllocator allocator(&cu_->arena_stack); 193755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko unsigned int num_blocks = GetNumBlocks(); 193855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko 1939622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko ScopedArenaQueue<BasicBlock*> q(allocator.Adapter()); 194055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ScopedArenaVector<size_t> visited_cnt_values(num_blocks, 0u, allocator.Adapter()); 194155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ScopedArenaVector<BasicBlockId> loop_head_stack(allocator.Adapter()); 194255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko size_t max_nested_loops = 0u; 194355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ArenaBitVector loop_exit_blocks(&allocator, num_blocks, false, kBitMapMisc); 194455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_exit_blocks.ClearAllBits(); 1945622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko 194655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Count the number of blocks to process and add the entry block(s). 194755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko unsigned int num_blocks_to_process = 0u; 1948e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (BasicBlock* bb : block_list_) { 194944e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler if (bb->hidden == true) { 195044e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler continue; 195144e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler } 195244e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 195355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko num_blocks_to_process += 1u; 1954622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko 1955e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko if (bb->predecessors.size() == 0u) { 195655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Add entry block to the queue. 195744e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler q.push(bb); 195844e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler } 195944e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler } 196044e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 1961e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko // Clear the topological order arrays. 1962e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_.clear(); 1963e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_.reserve(num_blocks); 1964e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_loop_ends_.clear(); 1965e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_loop_ends_.resize(num_blocks, 0u); 1966e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_indexes_.clear(); 1967e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_indexes_.resize(num_blocks, static_cast<uint16_t>(-1)); 196855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko 196955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Mark all blocks as unvisited. 197055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ClearAllVisitedFlags(); 197155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko 197255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // For loop heads, keep track from which blocks they are reachable not going through other 197355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // loop heads. Other loop heads are excluded to detect the heads of nested loops. The children 197455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // in this set go into the loop body, the other children are jumping over the loop. 197555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ScopedArenaVector<ArenaBitVector*> loop_head_reachable_from(allocator.Adapter()); 197655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_head_reachable_from.resize(num_blocks, nullptr); 197755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Reuse the same temp stack whenever calculating a loop_head_reachable_from[loop_head_id]. 197855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ScopedArenaVector<BasicBlockId> tmp_stack(allocator.Adapter()); 197955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko 198055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko while (num_blocks_to_process != 0u) { 1981622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko BasicBlock* bb = nullptr; 1982622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko if (!q.empty()) { 198355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko num_blocks_to_process -= 1u; 1984622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko // Get top. 1985622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko bb = q.front(); 1986622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko q.pop(); 198755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (bb->visited) { 198855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Loop head: it was already processed, mark end and copy exit blocks to the queue. 198955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko DCHECK(q.empty()) << PrettyMethod(cu_->method_idx, *cu_->dex_file); 1990e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko uint16_t idx = static_cast<uint16_t>(topological_order_.size()); 1991e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_loop_ends_[topological_order_indexes_[bb->id]] = idx; 199255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko DCHECK_EQ(loop_head_stack.back(), bb->id); 199355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_head_stack.pop_back(); 199455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ArenaBitVector* reachable = 199555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_head_stack.empty() ? nullptr : loop_head_reachable_from[loop_head_stack.back()]; 199655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko for (BasicBlockId candidate_id : loop_exit_blocks.Indexes()) { 199755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (reachable == nullptr || reachable->IsBitSet(candidate_id)) { 199855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko q.push(GetBasicBlock(candidate_id)); 199955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // NOTE: The BitVectorSet::IndexIterator will not check the pointed-to bit again, 200055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // so clearing the bit has no effect on the iterator. 200155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_exit_blocks.ClearBit(candidate_id); 200255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 200355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 200455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko continue; 200555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 2006622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko } else { 200755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Find the new loop head. 200855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko AllNodesIterator iter(this); 200955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko while (true) { 201055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko BasicBlock* candidate = iter.Next(); 201155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (candidate == nullptr) { 201255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // We did not find a true loop head, fall back to a reachable block in any loop. 201355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ArenaBitVector* current_loop = 201455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_head_stack.empty() ? nullptr : loop_head_reachable_from[loop_head_stack.back()]; 201555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko bb = SelectTopologicalSortOrderFallBack(this, current_loop, &visited_cnt_values, 201655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko &allocator, &tmp_stack); 201755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko DCHECK(bb != nullptr) << PrettyMethod(cu_->method_idx, *cu_->dex_file); 201855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (kIsDebugBuild && cu_->dex_file != nullptr) { 201955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko LOG(INFO) << "Topological sort order: Using fall-back in " 202055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko << PrettyMethod(cu_->method_idx, *cu_->dex_file) << " BB #" << bb->id 202155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko << " @0x" << std::hex << bb->start_offset 202255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko << ", num_blocks = " << std::dec << num_blocks; 202355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 202455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko break; 202555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 202655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (candidate->hidden || // Hidden, or 202755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko candidate->visited || // already processed, or 202855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko visited_cnt_values[candidate->id] == 0u || // no processed predecessors, or 202955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko (!loop_head_stack.empty() && // outside current loop. 203055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko !loop_head_reachable_from[loop_head_stack.back()]->IsBitSet(candidate->id))) { 2031622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko continue; 2032622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko } 203355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko 2034e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (BasicBlockId pred_id : candidate->predecessors) { 2035e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* pred_bb = GetBasicBlock(pred_id); 2036e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko DCHECK(pred_bb != nullptr); 203755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (pred_bb != candidate && !pred_bb->visited && 203855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko !pred_bb->dominators->IsBitSet(candidate->id)) { 2039e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko candidate = nullptr; // Set candidate to null to indicate failure. 2040e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko break; 2041622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko } 2042622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko } 2043e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko if (candidate != nullptr) { 204455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko bb = candidate; 204555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko break; 204655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 2047622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko } 204855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Compute blocks from which the loop head is reachable and process those blocks first. 204955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ArenaBitVector* reachable = 205055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko new (&allocator) ArenaBitVector(&allocator, num_blocks, false, kBitMapMisc); 205155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_head_reachable_from[bb->id] = reachable; 205255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko ComputeUnvisitedReachableFrom(this, bb->id, reachable, &tmp_stack); 205355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Now mark as loop head. (Even if it's only a fall back when we don't find a true loop.) 205455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_head_stack.push_back(bb->id); 205555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko max_nested_loops = std::max(max_nested_loops, loop_head_stack.size()); 2056622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko } 205744e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 205844e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler DCHECK_EQ(bb->hidden, false); 2059622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko DCHECK_EQ(bb->visited, false); 2060622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko bb->visited = true; 20618b858e16563ebf8e522df026a6ab409f1bd9b3deVladimir Marko bb->nesting_depth = loop_head_stack.size(); 206244e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 2063622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko // Now add the basic block. 2064e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko uint16_t idx = static_cast<uint16_t>(topological_order_.size()); 2065e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_indexes_[bb->id] = idx; 2066e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_.push_back(bb->id); 206744e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 206855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Update visited_cnt_values for children. 2069622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko ChildBlockIterator succIter(bb, this); 2070622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko BasicBlock* successor = succIter.Next(); 2071622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko for ( ; successor != nullptr; successor = succIter.Next()) { 207255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (successor->hidden) { 2073622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko continue; 2074622bdbe6c295b08d06dfaa8d896b9ca152aa899cVladimir Marko } 207544e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 207655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // One more predecessor was visited. 207755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko visited_cnt_values[successor->id] += 1u; 2078e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko if (visited_cnt_values[successor->id] == successor->predecessors.size()) { 207955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko if (loop_head_stack.empty() || 208055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_head_reachable_from[loop_head_stack.back()]->IsBitSet(successor->id)) { 208155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko q.push(successor); 208255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } else { 208355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko DCHECK(!loop_exit_blocks.IsBitSet(successor->id)); 208455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko loop_exit_blocks.SetBit(successor->id); 208555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko } 208644e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler } 208744e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler } 208844e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler } 208955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko 209055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko // Prepare the loop head stack for iteration. 2091e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_loop_head_stack_.clear(); 2092e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko topological_order_loop_head_stack_.reserve(max_nested_loops); 2093415ac88a6471792a28cf2b457fe4ba9dc099396eVladimir Marko max_nested_loops_ = max_nested_loops; 2094ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko topological_order_up_to_date_ = true; 209544e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler} 209644e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 209744e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beylerbool BasicBlock::IsExceptionBlock() const { 209844e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler if (block_type == kExceptionHandling) { 209944e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler return true; 210044e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler } 210144e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler return false; 210244e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler} 210344e5bdec17d0528b90cc0773be2beb76dcafdc5bJean Christophe Beyler 2104f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe BeylerChildBlockIterator::ChildBlockIterator(BasicBlock* bb, MIRGraph* mir_graph) 2105f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler : basic_block_(bb), mir_graph_(mir_graph), visited_fallthrough_(false), 2106f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler visited_taken_(false), have_successors_(false) { 2107f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler // Check if we actually do have successors. 2108f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler if (basic_block_ != 0 && basic_block_->successor_block_list_type != kNotUsed) { 2109f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler have_successors_ = true; 2110e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko successor_iter_ = basic_block_->successor_blocks.cbegin(); 2111f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler } 2112f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler} 2113f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler 2114f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe BeylerBasicBlock* ChildBlockIterator::Next() { 2115f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler // We check if we have a basic block. If we don't we cannot get next child. 2116f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler if (basic_block_ == nullptr) { 2117f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler return nullptr; 2118f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler } 2119f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler 2120f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler // If we haven't visited fallthrough, return that. 2121f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler if (visited_fallthrough_ == false) { 2122f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler visited_fallthrough_ = true; 2123f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler 2124f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler BasicBlock* result = mir_graph_->GetBasicBlock(basic_block_->fall_through); 2125f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler if (result != nullptr) { 2126f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler return result; 2127f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler } 2128f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler } 2129f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler 2130f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler // If we haven't visited taken, return that. 2131f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler if (visited_taken_ == false) { 2132f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler visited_taken_ = true; 2133f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler 2134f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler BasicBlock* result = mir_graph_->GetBasicBlock(basic_block_->taken); 2135f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler if (result != nullptr) { 2136f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler return result; 2137f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler } 2138f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler } 2139f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler 2140f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler // We visited both taken and fallthrough. Now check if we have successors we need to visit. 2141f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler if (have_successors_ == true) { 2142f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler // Get information about next successor block. 2143e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko auto end = basic_block_->successor_blocks.cend(); 2144e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko while (successor_iter_ != end) { 2145e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko SuccessorBlockInfo* successor_block_info = *successor_iter_; 2146e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko ++successor_iter_; 2147989367a47b015dd85f850cf756b436fb044b5aeaNiranjan Kumar // If block was replaced by zero block, take next one. 2148989367a47b015dd85f850cf756b436fb044b5aeaNiranjan Kumar if (successor_block_info->block != NullBasicBlockId) { 2149989367a47b015dd85f850cf756b436fb044b5aeaNiranjan Kumar return mir_graph_->GetBasicBlock(successor_block_info->block); 2150989367a47b015dd85f850cf756b436fb044b5aeaNiranjan Kumar } 2151f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler } 2152f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler } 2153f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler 2154f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler // We do not have anything. 2155f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler return nullptr; 2156f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler} 2157f8c762b8cbd4a223c697d7e7bdb976fb39224cb8Jean Christophe Beyler 21588512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe BeylerBasicBlock* BasicBlock::Copy(CompilationUnit* c_unit) { 21598512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler MIRGraph* mir_graph = c_unit->mir_graph.get(); 21608512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return Copy(mir_graph); 21618512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 21623aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 21638512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe BeylerBasicBlock* BasicBlock::Copy(MIRGraph* mir_graph) { 21648512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler BasicBlock* result_bb = mir_graph->CreateNewBB(block_type); 21653aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 21668512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // We don't do a memcpy style copy here because it would lead to a lot of things 21678512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // to clean up. Let us do it by hand instead. 21688512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Copy in taken and fallthrough. 21698512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler result_bb->fall_through = fall_through; 21708512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler result_bb->taken = taken; 21713aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 21728512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Copy successor links if needed. 21738512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler ArenaAllocator* arena = mir_graph->GetArena(); 21743aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 21758512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler result_bb->successor_block_list_type = successor_block_list_type; 21768512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (result_bb->successor_block_list_type != kNotUsed) { 2177e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko result_bb->successor_blocks.reserve(successor_blocks.size()); 2178e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (SuccessorBlockInfo* sbi_old : successor_blocks) { 2179e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko SuccessorBlockInfo* sbi_new = static_cast<SuccessorBlockInfo*>( 2180e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko arena->Alloc(sizeof(SuccessorBlockInfo), kArenaAllocSuccessor)); 21818512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler memcpy(sbi_new, sbi_old, sizeof(SuccessorBlockInfo)); 2182e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko result_bb->successor_blocks.push_back(sbi_new); 21833aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler } 21848512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 21853aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 21868512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Copy offset, method. 21878512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler result_bb->start_offset = start_offset; 21883aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 21898512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Now copy instructions. 21908512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler for (MIR* mir = first_mir_insn; mir != 0; mir = mir->next) { 21918512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Get a copy first. 21928512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler MIR* copy = mir->Copy(mir_graph); 21933aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 21948512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Append it. 21958512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler result_bb->AppendMIR(copy); 21963aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler } 21973aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 21988512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return result_bb; 21993aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler} 22003aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 22013aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe BeylerMIR* MIR::Copy(MIRGraph* mir_graph) { 22023aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler MIR* res = mir_graph->NewMIR(); 22033aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler *res = *this; 22043aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 22053aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler // Remove links 22063aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler res->next = nullptr; 22073aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler res->bb = NullBasicBlockId; 22083aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler res->ssa_rep = nullptr; 22093aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 22103aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler return res; 22113aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler} 22123aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 22133aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe BeylerMIR* MIR::Copy(CompilationUnit* c_unit) { 22143aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler return Copy(c_unit->mir_graph.get()); 22153aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler} 22163aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 22173aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyleruint32_t SSARepresentation::GetStartUseIndex(Instruction::Code opcode) { 22183aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler // Default result. 22193aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler int res = 0; 22203aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 22213aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler // We are basically setting the iputs to their igets counterparts. 22223aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler switch (opcode) { 22233aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT: 22243aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT_OBJECT: 22253aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT_BOOLEAN: 22263aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT_BYTE: 22273aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT_CHAR: 22283aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT_SHORT: 22293aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT_QUICK: 22303aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT_OBJECT_QUICK: 223137f05ef45e0393de812d51261dc293240c17294dFred Shih case Instruction::IPUT_BOOLEAN_QUICK: 223237f05ef45e0393de812d51261dc293240c17294dFred Shih case Instruction::IPUT_BYTE_QUICK: 223337f05ef45e0393de812d51261dc293240c17294dFred Shih case Instruction::IPUT_CHAR_QUICK: 223437f05ef45e0393de812d51261dc293240c17294dFred Shih case Instruction::IPUT_SHORT_QUICK: 22353aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::APUT: 22363aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::APUT_OBJECT: 22373aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::APUT_BOOLEAN: 22383aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::APUT_BYTE: 22393aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::APUT_CHAR: 22403aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::APUT_SHORT: 22413aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::SPUT: 22423aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::SPUT_OBJECT: 22433aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::SPUT_BOOLEAN: 22443aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::SPUT_BYTE: 22453aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::SPUT_CHAR: 22463aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::SPUT_SHORT: 22473aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler // Skip the VR containing what to store. 22483aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler res = 1; 22493aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler break; 22503aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT_WIDE: 22513aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::IPUT_WIDE_QUICK: 22523aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::APUT_WIDE: 22533aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler case Instruction::SPUT_WIDE: 22543aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler // Skip the two VRs containing what to store. 22553aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler res = 2; 22563aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler break; 22573aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler default: 22583aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler // Do nothing in the general case. 22593aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler break; 22603aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler } 22613aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 22623aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler return res; 22633aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler} 22643aa57730e2aec451bb836918d936c6862598d8d6Jean Christophe Beyler 2265c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler/** 2266c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler * @brief Given a decoded instruction, it checks whether the instruction 2267c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler * sets a constant and if it does, more information is provided about the 2268c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler * constant being set. 2269c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler * @param ptr_value pointer to a 64-bit holder for the constant. 2270c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler * @param wide Updated by function whether a wide constant is being set by bytecode. 2271c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler * @return Returns false if the decoded instruction does not represent a constant bytecode. 2272c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler */ 2273c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beylerbool MIR::DecodedInstruction::GetConstant(int64_t* ptr_value, bool* wide) const { 2274c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler bool sets_const = true; 2275c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler int64_t value = vB; 2276c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler 2277c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler DCHECK(ptr_value != nullptr); 2278c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler DCHECK(wide != nullptr); 2279c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler 2280c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler switch (opcode) { 2281c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler case Instruction::CONST_4: 2282c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler case Instruction::CONST_16: 2283c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler case Instruction::CONST: 2284c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler *wide = false; 2285c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler value <<= 32; // In order to get the sign extend. 2286c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler value >>= 32; 2287c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler break; 2288c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler case Instruction::CONST_HIGH16: 2289c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler *wide = false; 2290c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler value <<= 48; // In order to get the sign extend. 2291c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler value >>= 32; 2292c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler break; 2293c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler case Instruction::CONST_WIDE_16: 2294c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler case Instruction::CONST_WIDE_32: 2295c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler *wide = true; 2296c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler value <<= 32; // In order to get the sign extend. 2297c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler value >>= 32; 2298c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler break; 2299c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler case Instruction::CONST_WIDE: 2300c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler *wide = true; 2301c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler value = vB_wide; 2302c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler break; 2303c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler case Instruction::CONST_WIDE_HIGH16: 2304c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler *wide = true; 2305c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler value <<= 48; // In order to get the sign extend. 2306c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler break; 2307c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler default: 2308c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler sets_const = false; 2309c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler break; 2310c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler } 2311c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler 2312c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler if (sets_const) { 2313c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler *ptr_value = value; 2314c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler } 2315c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler 2316c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler return sets_const; 2317c3db20b7e6f847339d6ecbd89846c173a7ccc967Jean Christophe Beyler} 23188512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23198512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylervoid BasicBlock::ResetOptimizationFlags(uint16_t reset_flags) { 23208512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Reset flags for all MIRs in bb. 23212cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier for (MIR* mir = first_mir_insn; mir != nullptr; mir = mir->next) { 23228512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler mir->optimization_flags &= (~reset_flags); 23238512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 23248512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 23258512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 2326cb873d8fd06b7dde4b69c5987b4eaf541d345a50Vladimir Markovoid BasicBlock::Kill(MIRGraph* mir_graph) { 2327e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (BasicBlockId pred_id : predecessors) { 2328e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko BasicBlock* pred_bb = mir_graph->GetBasicBlock(pred_id); 2329e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko DCHECK(pred_bb != nullptr); 23308512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23318512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Sadly we have to go through the children by hand here. 23328512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler pred_bb->ReplaceChild(id, NullBasicBlockId); 23338512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 2334cb873d8fd06b7dde4b69c5987b4eaf541d345a50Vladimir Marko predecessors.clear(); 23358512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 2336312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko // Mark as dead and hidden. 2337312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko block_type = kDead; 2338312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko hidden = true; 2339312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko 2340312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko // Detach it from its MIRs so we don't generate code for them. Also detached MIRs 2341312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko // are updated to know that they no longer have a parent. 2342312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko for (MIR* mir = first_mir_insn; mir != nullptr; mir = mir->next) { 2343312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko mir->bb = NullBasicBlockId; 2344312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko } 2345312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko first_mir_insn = nullptr; 2346312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko last_mir_insn = nullptr; 2347312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko 2348312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko data_flow_info = nullptr; 2349312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko 2350312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko // Erase this bb from all children's predecessors and kill unreachable children. 2351312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko ChildBlockIterator iter(this, mir_graph); 2352312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko for (BasicBlock* succ_bb = iter.Next(); succ_bb != nullptr; succ_bb = iter.Next()) { 2353312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko succ_bb->ErasePredecessor(id); 2354312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko } 2355312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko 2356312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko // Remove links to children. 2357312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko fall_through = NullBasicBlockId; 2358312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko taken = NullBasicBlockId; 2359312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko successor_block_list_type = kNotUsed; 2360312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko 2361312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko if (kIsDebugBuild) { 2362312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko if (catch_entry) { 2363312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko DCHECK_EQ(mir_graph->catches_.count(start_offset), 1u); 2364312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko mir_graph->catches_.erase(start_offset); 2365312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko } 2366312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko } 2367312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko} 2368312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko 23698512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylerbool BasicBlock::IsSSALiveOut(const CompilationUnit* c_unit, int ssa_reg) { 23708512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // In order to determine if the ssa reg is live out, we scan all the MIRs. We remember 23718512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // the last SSA number of the same dalvik register. At the end, if it is different than ssa_reg, 23728512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // then it is not live out of this BB. 23738512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler int dalvik_reg = c_unit->mir_graph->SRegToVReg(ssa_reg); 23748512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23758512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler int last_ssa_reg = -1; 23768512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23778512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Walk through the MIRs backwards. 23788512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler for (MIR* mir = first_mir_insn; mir != nullptr; mir = mir->next) { 23798512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Get ssa rep. 23808512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler SSARepresentation *ssa_rep = mir->ssa_rep; 23818512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23828512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Go through the defines for this MIR. 23838512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler for (int i = 0; i < ssa_rep->num_defs; i++) { 23848512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler DCHECK(ssa_rep->defs != nullptr); 23858512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23868512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Get the ssa reg. 23878512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler int def_ssa_reg = ssa_rep->defs[i]; 23888512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23898512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Get dalvik reg. 23908512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler int def_dalvik_reg = c_unit->mir_graph->SRegToVReg(def_ssa_reg); 23918512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 23928512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Compare dalvik regs. 23938512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (dalvik_reg == def_dalvik_reg) { 23948512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // We found a def of the register that we are being asked about. 23958512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Remember it. 23968512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler last_ssa_reg = def_ssa_reg; 23978512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 23988512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 23998512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 24008512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 24018512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (last_ssa_reg == -1) { 24028512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // If we get to this point we couldn't find a define of register user asked about. 24038512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // Let's assume the user knows what he's doing so we can be safe and say that if we 24048512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // couldn't find a def, it is live out. 24058512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return true; 24068512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 24078512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 24088512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // If it is not -1, we found a match, is it ssa_reg? 24098512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return (ssa_reg == last_ssa_reg); 24108512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 24118512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 24128512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beylerbool BasicBlock::ReplaceChild(BasicBlockId old_bb, BasicBlockId new_bb) { 24138512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler // We need to check taken, fall_through, and successor_blocks to replace. 24148512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler bool found = false; 24158512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (taken == old_bb) { 24168512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler taken = new_bb; 24178512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler found = true; 24188512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 24198512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 24208512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (fall_through == old_bb) { 24218512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler fall_through = new_bb; 24228512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler found = true; 24238512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 24248512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 24258512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (successor_block_list_type != kNotUsed) { 2426e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko for (SuccessorBlockInfo* successor_block_info : successor_blocks) { 24278512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler if (successor_block_info->block == old_bb) { 24288512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler successor_block_info->block = new_bb; 24298512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler found = true; 24308512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 24318512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 24328512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 24338512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 24348512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return found; 24358512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 24368512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 2437e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Markovoid BasicBlock::ErasePredecessor(BasicBlockId old_pred) { 2438e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko auto pos = std::find(predecessors.begin(), predecessors.end(), old_pred); 2439e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko DCHECK(pos != predecessors.end()); 2440312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko // It's faster to move the back() to *pos than erase(pos). 2441312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko *pos = predecessors.back(); 2442312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko predecessors.pop_back(); 2443312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko size_t idx = std::distance(predecessors.begin(), pos); 2444312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko for (MIR* mir = first_mir_insn; mir != nullptr; mir = mir->next) { 2445312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko if (static_cast<int>(mir->dalvikInsn.opcode) != kMirOpPhi) { 2446312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko break; 2447312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko } 2448312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko DCHECK_EQ(mir->ssa_rep->num_uses - 1u, predecessors.size()); 2449312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko DCHECK_EQ(mir->meta.phi_incoming[idx], old_pred); 2450312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko mir->meta.phi_incoming[idx] = mir->meta.phi_incoming[predecessors.size()]; 2451312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko mir->ssa_rep->uses[idx] = mir->ssa_rep->uses[predecessors.size()]; 2452312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko mir->ssa_rep->num_uses = predecessors.size(); 2453312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko } 2454e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko} 24558512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 2456e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Markovoid BasicBlock::UpdatePredecessor(BasicBlockId old_pred, BasicBlockId new_pred) { 2457e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko DCHECK_NE(new_pred, NullBasicBlockId); 2458e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko auto pos = std::find(predecessors.begin(), predecessors.end(), old_pred); 2459312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko DCHECK(pos != predecessors.end()); 2460312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko *pos = new_pred; 2461312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko size_t idx = std::distance(predecessors.begin(), pos); 2462312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko for (MIR* mir = first_mir_insn; mir != nullptr; mir = mir->next) { 2463312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko if (static_cast<int>(mir->dalvikInsn.opcode) != kMirOpPhi) { 2464312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko break; 2465312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko } 2466312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko DCHECK_EQ(mir->meta.phi_incoming[idx], old_pred); 2467312eb25273dc0e2f8880d80f00c5b0998febaf7bVladimir Marko mir->meta.phi_incoming[idx] = new_pred; 24688512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler } 24698512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 24708512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 24718512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler// Create a new basic block with block_id as num_blocks_ that is 24728512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler// post-incremented. 24738512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe BeylerBasicBlock* MIRGraph::CreateNewBB(BBType block_type) { 2474ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko BasicBlockId id = static_cast<BasicBlockId>(block_list_.size()); 2475ffda4993af78484feb7a4ce5497c1796463c0ba1Vladimir Marko BasicBlock* res = NewMemBB(block_type, id); 2476e39c54ea575ec710d5e84277fcdcc049f8acb3c9Vladimir Marko block_list_.push_back(res); 24778512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler return res; 24788512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler} 24798512758d1208d3c32bf67db9c925b8fc6e077fd7Jean Christophe Beyler 2480216eaa2927f424821a03d7c4c6bf701fdb48e865Nicolas Geoffrayvoid MIRGraph::CalculateBasicBlockInformation(const PassManager* const post_opt_pass_manager) { 24815bdab12d8b48ca4c395d9d2c506ebff0df01b734Mathieu Chartier /* Create the pass driver and launch it */ 2482216eaa2927f424821a03d7c4c6bf701fdb48e865Nicolas Geoffray PassDriverMEPostOpt driver(post_opt_pass_manager, cu_); 24832469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler driver.Launch(); 24842469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler} 24852469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler 2486fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beylerint MIR::DecodedInstruction::FlagsOf() const { 2487fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler // Calculate new index. 2488fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler int idx = static_cast<int>(opcode) - kNumPackedOpcodes; 2489fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler 2490fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler // Check if it is an extended or not. 2491fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler if (idx < 0) { 2492fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::FlagsOf(opcode); 2493fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler } 2494fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler 2495fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler // For extended, we use a switch. 2496fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler switch (static_cast<int>(opcode)) { 2497fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPhi: 2498fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2499fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpCopy: 2500fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2501fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpFusedCmplFloat: 2502fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue | Instruction::kBranch; 2503fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpFusedCmpgFloat: 2504fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue | Instruction::kBranch; 2505fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpFusedCmplDouble: 2506fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue | Instruction::kBranch; 2507fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpFusedCmpgDouble: 2508fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue | Instruction::kBranch; 2509fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpFusedCmpLong: 2510fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue | Instruction::kBranch; 2511fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpNop: 2512fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2513fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpNullCheck: 2514fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue | Instruction::kThrow; 2515fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpRangeCheck: 2516fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue | Instruction::kThrow; 2517fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpDivZeroCheck: 2518fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue | Instruction::kThrow; 2519fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpCheck: 2520b7fc629dc562ee9f3df04a112a70b7868664f94dUdayan Banerji return Instruction::kContinue | Instruction::kThrow; 2521fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpSelect: 2522fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2523fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpConstVector: 2524fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2525fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpMoveVector: 2526fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2527fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedMultiply: 2528fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2529fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedAddition: 2530fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2531fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedSubtract: 2532fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2533fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedShiftLeft: 2534fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2535fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedSignedShiftRight: 2536fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2537fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedUnsignedShiftRight: 2538fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2539fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedAnd: 2540fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2541fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedOr: 2542fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2543fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedXor: 2544fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2545fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedAddReduce: 2546fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2547fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedReduce: 2548fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2549fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpPackedSet: 2550fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2551fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpReserveVectorRegisters: 2552fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2553fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler case kMirOpReturnVectorRegisters: 2554fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return Instruction::kContinue; 2555b7fc629dc562ee9f3df04a112a70b7868664f94dUdayan Banerji case kMirOpMemBarrier: 2556b7fc629dc562ee9f3df04a112a70b7868664f94dUdayan Banerji return Instruction::kContinue; 2557b7fc629dc562ee9f3df04a112a70b7868664f94dUdayan Banerji case kMirOpPackedArrayGet: 2558b7fc629dc562ee9f3df04a112a70b7868664f94dUdayan Banerji return Instruction::kContinue | Instruction::kThrow; 2559b7fc629dc562ee9f3df04a112a70b7868664f94dUdayan Banerji case kMirOpPackedArrayPut: 2560b7fc629dc562ee9f3df04a112a70b7868664f94dUdayan Banerji return Instruction::kContinue | Instruction::kThrow; 2561a262f7707330dccfb50af6345813083182b61043Ningsheng Jian case kMirOpMaddInt: 2562a262f7707330dccfb50af6345813083182b61043Ningsheng Jian case kMirOpMsubInt: 2563a262f7707330dccfb50af6345813083182b61043Ningsheng Jian case kMirOpMaddLong: 2564a262f7707330dccfb50af6345813083182b61043Ningsheng Jian case kMirOpMsubLong: 2565a262f7707330dccfb50af6345813083182b61043Ningsheng Jian return Instruction::kContinue; 2566fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler default: 2567fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler LOG(WARNING) << "ExtendedFlagsOf: Unhandled case: " << static_cast<int> (opcode); 2568fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler return 0; 2569fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler } 2570fb0ea2df9a52e5db18e1aa85da282938bbd92f2eJean Christophe Beyler} 25710b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe 25720b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampeconst uint16_t* MIRGraph::GetInsns(int m_unit_index) const { 25730b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe return m_units_[m_unit_index]->GetCodeItem()->insns_; 25740b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe} 25750b9203e7996ee1856f620f95d95d8a273c43a3dfAndreas Gampe 25767a01dc2107d4255b445c32867d15d45fcebb3acdVladimir Markovoid MIRGraph::SetPuntToInterpreter(bool val) { 25777a01dc2107d4255b445c32867d15d45fcebb3acdVladimir Marko punt_to_interpreter_ = val; 25787a01dc2107d4255b445c32867d15d45fcebb3acdVladimir Marko if (val) { 25797a01dc2107d4255b445c32867d15d45fcebb3acdVladimir Marko // Disable all subsequent optimizations. They may not be safe to run. (For example, 25807a01dc2107d4255b445c32867d15d45fcebb3acdVladimir Marko // LVN/GVN assumes there are no conflicts found by the type inference pass.) 25817a01dc2107d4255b445c32867d15d45fcebb3acdVladimir Marko cu_->disable_opt = ~static_cast<decltype(cu_->disable_opt)>(0); 25827a01dc2107d4255b445c32867d15d45fcebb3acdVladimir Marko } 25837a01dc2107d4255b445c32867d15d45fcebb3acdVladimir Marko} 25847a01dc2107d4255b445c32867d15d45fcebb3acdVladimir Marko 25857934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom} // namespace art 2586