| David Brazdil | 86ea7ee | 2016-02-16 09:26:07 +0000 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright (C) 2016 The Android Open Source Project | 
|  | 3 | * | 
|  | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 5 | * you may not use this file except in compliance with the License. | 
|  | 6 | * You may obtain a copy of the License at | 
|  | 7 | * | 
|  | 8 | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 9 | * | 
|  | 10 | * Unless required by applicable law or agreed to in writing, software | 
|  | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 13 | * See the License for the specific language governing permissions and | 
|  | 14 | * limitations under the License. | 
|  | 15 | */ | 
|  | 16 |  | 
|  | 17 | #ifndef ART_COMPILER_OPTIMIZING_BLOCK_BUILDER_H_ | 
|  | 18 | #define ART_COMPILER_OPTIMIZING_BLOCK_BUILDER_H_ | 
|  | 19 |  | 
|  | 20 | #include "base/arena_containers.h" | 
|  | 21 | #include "base/arena_object.h" | 
|  | 22 | #include "dex_file.h" | 
|  | 23 | #include "nodes.h" | 
|  | 24 |  | 
|  | 25 | namespace art { | 
|  | 26 |  | 
|  | 27 | class HBasicBlockBuilder : public ValueObject { | 
|  | 28 | public: | 
|  | 29 | HBasicBlockBuilder(HGraph* graph, | 
|  | 30 | const DexFile* const dex_file, | 
|  | 31 | const DexFile::CodeItem& code_item) | 
|  | 32 | : arena_(graph->GetArena()), | 
|  | 33 | graph_(graph), | 
|  | 34 | dex_file_(dex_file), | 
|  | 35 | code_item_(code_item), | 
|  | 36 | branch_targets_(code_item.insns_size_in_code_units_, | 
|  | 37 | nullptr, | 
|  | 38 | arena_->Adapter(kArenaAllocGraphBuilder)), | 
|  | 39 | throwing_blocks_(kDefaultNumberOfThrowingBlocks, arena_->Adapter(kArenaAllocGraphBuilder)), | 
| Mathieu Chartier | de4b08f | 2017-07-10 14:13:41 -0700 | [diff] [blame] | 40 | number_of_branches_(0u), | 
|  | 41 | quicken_index_for_dex_pc_(std::less<uint32_t>(), arena_->Adapter()) {} | 
| David Brazdil | 86ea7ee | 2016-02-16 09:26:07 +0000 | [diff] [blame] | 42 |  | 
|  | 43 | // Creates basic blocks in `graph_` at branch target dex_pc positions of the | 
|  | 44 | // `code_item_`. Blocks are connected but left unpopulated with instructions. | 
|  | 45 | // TryBoundary blocks are inserted at positions where control-flow enters/ | 
|  | 46 | // exits a try block. | 
|  | 47 | bool Build(); | 
|  | 48 |  | 
|  | 49 | size_t GetNumberOfBranches() const { return number_of_branches_; } | 
|  | 50 | HBasicBlock* GetBlockAt(uint32_t dex_pc) const { return branch_targets_[dex_pc]; } | 
|  | 51 |  | 
| Mathieu Chartier | de4b08f | 2017-07-10 14:13:41 -0700 | [diff] [blame] | 52 | size_t GetQuickenIndex(uint32_t dex_pc) const; | 
|  | 53 |  | 
| David Brazdil | 86ea7ee | 2016-02-16 09:26:07 +0000 | [diff] [blame] | 54 | private: | 
|  | 55 | // Creates a basic block starting at given `dex_pc`. | 
|  | 56 | HBasicBlock* MaybeCreateBlockAt(uint32_t dex_pc); | 
|  | 57 |  | 
|  | 58 | // Creates a basic block for bytecode instructions at `semantic_dex_pc` and | 
|  | 59 | // stores it under the `store_dex_pc` key. This is used when multiple blocks | 
|  | 60 | // share the same semantic dex_pc, e.g. when building switch decision trees. | 
|  | 61 | HBasicBlock* MaybeCreateBlockAt(uint32_t semantic_dex_pc, uint32_t store_dex_pc); | 
|  | 62 |  | 
|  | 63 | bool CreateBranchTargets(); | 
|  | 64 | void ConnectBasicBlocks(); | 
|  | 65 | void InsertTryBoundaryBlocks(); | 
|  | 66 |  | 
|  | 67 | // Helper method which decides whether `catch_block` may have live normal | 
|  | 68 | // predecessors and thus whether a synthetic catch block needs to be created | 
|  | 69 | // to avoid mixing normal and exceptional predecessors. | 
|  | 70 | // Should only be called during InsertTryBoundaryBlocks on blocks at catch | 
|  | 71 | // handler dex_pcs. | 
|  | 72 | bool MightHaveLiveNormalPredecessors(HBasicBlock* catch_block); | 
|  | 73 |  | 
|  | 74 | ArenaAllocator* const arena_; | 
|  | 75 | HGraph* const graph_; | 
|  | 76 |  | 
|  | 77 | const DexFile* const dex_file_; | 
|  | 78 | const DexFile::CodeItem& code_item_; | 
|  | 79 |  | 
|  | 80 | ArenaVector<HBasicBlock*> branch_targets_; | 
|  | 81 | ArenaVector<HBasicBlock*> throwing_blocks_; | 
|  | 82 | size_t number_of_branches_; | 
|  | 83 |  | 
| Mathieu Chartier | de4b08f | 2017-07-10 14:13:41 -0700 | [diff] [blame] | 84 | // A table to quickly find the quicken index for the first instruction of a basic block. | 
|  | 85 | ArenaSafeMap<uint32_t, uint32_t> quicken_index_for_dex_pc_; | 
|  | 86 |  | 
| David Brazdil | 86ea7ee | 2016-02-16 09:26:07 +0000 | [diff] [blame] | 87 | static constexpr size_t kDefaultNumberOfThrowingBlocks = 2u; | 
|  | 88 |  | 
|  | 89 | DISALLOW_COPY_AND_ASSIGN(HBasicBlockBuilder); | 
|  | 90 | }; | 
|  | 91 |  | 
|  | 92 | }  // namespace art | 
|  | 93 |  | 
|  | 94 | #endif  // ART_COMPILER_OPTIMIZING_BLOCK_BUILDER_H_ |