• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
HBasicBlockBuilder(HGraph * graph,const DexFile * const dex_file,const DexFile::CodeItem & code_item)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)),
40          number_of_branches_(0u) {}
41  
42    // Creates basic blocks in `graph_` at branch target dex_pc positions of the
43    // `code_item_`. Blocks are connected but left unpopulated with instructions.
44    // TryBoundary blocks are inserted at positions where control-flow enters/
45    // exits a try block.
46    bool Build();
47  
GetNumberOfBranches()48    size_t GetNumberOfBranches() const { return number_of_branches_; }
GetBlockAt(uint32_t dex_pc)49    HBasicBlock* GetBlockAt(uint32_t dex_pc) const { return branch_targets_[dex_pc]; }
50  
51   private:
52    // Creates a basic block starting at given `dex_pc`.
53    HBasicBlock* MaybeCreateBlockAt(uint32_t dex_pc);
54  
55    // Creates a basic block for bytecode instructions at `semantic_dex_pc` and
56    // stores it under the `store_dex_pc` key. This is used when multiple blocks
57    // share the same semantic dex_pc, e.g. when building switch decision trees.
58    HBasicBlock* MaybeCreateBlockAt(uint32_t semantic_dex_pc, uint32_t store_dex_pc);
59  
60    bool CreateBranchTargets();
61    void ConnectBasicBlocks();
62    void InsertTryBoundaryBlocks();
63  
64    // Helper method which decides whether `catch_block` may have live normal
65    // predecessors and thus whether a synthetic catch block needs to be created
66    // to avoid mixing normal and exceptional predecessors.
67    // Should only be called during InsertTryBoundaryBlocks on blocks at catch
68    // handler dex_pcs.
69    bool MightHaveLiveNormalPredecessors(HBasicBlock* catch_block);
70  
71    ArenaAllocator* const arena_;
72    HGraph* const graph_;
73  
74    const DexFile* const dex_file_;
75    const DexFile::CodeItem& code_item_;
76  
77    ArenaVector<HBasicBlock*> branch_targets_;
78    ArenaVector<HBasicBlock*> throwing_blocks_;
79    size_t number_of_branches_;
80  
81    static constexpr size_t kDefaultNumberOfThrowingBlocks = 2u;
82  
83    DISALLOW_COPY_AND_ASSIGN(HBasicBlockBuilder);
84  };
85  
86  }  // namespace art
87  
88  #endif  // ART_COMPILER_OPTIMIZING_BLOCK_BUILDER_H_
89