186ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil/* 286ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil * Copyright (C) 2016 The Android Open Source Project 386ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil * 486ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil * Licensed under the Apache License, Version 2.0 (the "License"); 586ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil * you may not use this file except in compliance with the License. 686ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil * You may obtain a copy of the License at 786ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil * 886ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil * http://www.apache.org/licenses/LICENSE-2.0 986ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil * 1086ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil * Unless required by applicable law or agreed to in writing, software 1186ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil * distributed under the License is distributed on an "AS IS" BASIS, 1286ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1386ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil * See the License for the specific language governing permissions and 1486ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil * limitations under the License. 1586ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil */ 1686ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil 1786ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil#ifndef ART_COMPILER_OPTIMIZING_BLOCK_BUILDER_H_ 1886ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil#define ART_COMPILER_OPTIMIZING_BLOCK_BUILDER_H_ 1986ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil 2086ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil#include "base/arena_containers.h" 2186ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil#include "base/arena_object.h" 2286ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil#include "dex_file.h" 2386ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil#include "nodes.h" 2486ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil 2586ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdilnamespace art { 2686ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil 2786ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdilclass HBasicBlockBuilder : public ValueObject { 2886ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil public: 2986ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil HBasicBlockBuilder(HGraph* graph, 3086ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil const DexFile* const dex_file, 3186ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil const DexFile::CodeItem& code_item) 3286ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil : arena_(graph->GetArena()), 3386ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil graph_(graph), 3486ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil dex_file_(dex_file), 3586ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil code_item_(code_item), 3686ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil branch_targets_(code_item.insns_size_in_code_units_, 3786ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil nullptr, 3886ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil arena_->Adapter(kArenaAllocGraphBuilder)), 3986ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil throwing_blocks_(kDefaultNumberOfThrowingBlocks, arena_->Adapter(kArenaAllocGraphBuilder)), 4086ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil number_of_branches_(0u) {} 4186ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil 4286ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil // Creates basic blocks in `graph_` at branch target dex_pc positions of the 4386ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil // `code_item_`. Blocks are connected but left unpopulated with instructions. 4486ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil // TryBoundary blocks are inserted at positions where control-flow enters/ 4586ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil // exits a try block. 4686ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil bool Build(); 4786ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil 4886ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil size_t GetNumberOfBranches() const { return number_of_branches_; } 4986ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil HBasicBlock* GetBlockAt(uint32_t dex_pc) const { return branch_targets_[dex_pc]; } 5086ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil 5186ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil private: 5286ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil // Creates a basic block starting at given `dex_pc`. 5386ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil HBasicBlock* MaybeCreateBlockAt(uint32_t dex_pc); 5486ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil 5586ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil // Creates a basic block for bytecode instructions at `semantic_dex_pc` and 5686ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil // stores it under the `store_dex_pc` key. This is used when multiple blocks 5786ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil // share the same semantic dex_pc, e.g. when building switch decision trees. 5886ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil HBasicBlock* MaybeCreateBlockAt(uint32_t semantic_dex_pc, uint32_t store_dex_pc); 5986ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil 6086ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil bool CreateBranchTargets(); 6186ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil void ConnectBasicBlocks(); 6286ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil void InsertTryBoundaryBlocks(); 6386ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil 6486ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil // Helper method which decides whether `catch_block` may have live normal 6586ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil // predecessors and thus whether a synthetic catch block needs to be created 6686ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil // to avoid mixing normal and exceptional predecessors. 6786ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil // Should only be called during InsertTryBoundaryBlocks on blocks at catch 6886ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil // handler dex_pcs. 6986ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil bool MightHaveLiveNormalPredecessors(HBasicBlock* catch_block); 7086ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil 7186ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil ArenaAllocator* const arena_; 7286ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil HGraph* const graph_; 7386ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil 7486ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil const DexFile* const dex_file_; 7586ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil const DexFile::CodeItem& code_item_; 7686ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil 7786ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil ArenaVector<HBasicBlock*> branch_targets_; 7886ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil ArenaVector<HBasicBlock*> throwing_blocks_; 7986ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil size_t number_of_branches_; 8086ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil 8186ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil static constexpr size_t kDefaultNumberOfThrowingBlocks = 2u; 8286ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil 8386ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil DISALLOW_COPY_AND_ASSIGN(HBasicBlockBuilder); 8486ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil}; 8586ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil 8686ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil} // namespace art 8786ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil 8886ea7eeabe30c98bbe1651a51d03cb89776724e7David Brazdil#endif // ART_COMPILER_OPTIMIZING_BLOCK_BUILDER_H_ 89