summaryrefslogtreecommitdiffstats
path: root/compiler/optimizing/builder.h
blob: e143786be7db953e314e858c01bb2220c83013a6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_COMPILER_OPTIMIZING_BUILDER_H_
#define ART_COMPILER_OPTIMIZING_BUILDER_H_

#include "dex_file.h"
#include "driver/compiler_driver.h"
#include "driver/dex_compilation_unit.h"
#include "primitive.h"
#include "utils/allocation.h"
#include "utils/growable_array.h"
#include "nodes.h"

namespace art {

class Instruction;

class HGraphBuilder : public ValueObject {
 public:
  HGraphBuilder(ArenaAllocator* arena,
                DexCompilationUnit* dex_compilation_unit = nullptr,
                const DexFile* dex_file = nullptr,
                CompilerDriver* driver = nullptr)
      : arena_(arena),
        branch_targets_(arena, 0),
        locals_(arena, 0),
        entry_block_(nullptr),
        exit_block_(nullptr),
        current_block_(nullptr),
        graph_(nullptr),
        constant0_(nullptr),
        constant1_(nullptr),
        dex_file_(dex_file),
        dex_compilation_unit_(dex_compilation_unit),
        compiler_driver_(driver) {}

  HGraph* BuildGraph(const DexFile::CodeItem& code);

 private:
  // Analyzes the dex instruction and adds HInstruction to the graph
  // to execute that instruction. Returns whether the instruction can
  // be handled.
  bool AnalyzeDexInstruction(const Instruction& instruction, uint32_t dex_offset);

  // Finds all instructions that start a new block, and populates branch_targets_ with
  // the newly created blocks.
  void ComputeBranchTargets(const uint16_t* start, const uint16_t* end);
  void MaybeUpdateCurrentBlock(size_t index);
  HBasicBlock* FindBlockStartingAt(int32_t index) const;

  HIntConstant* GetIntConstant0();
  HIntConstant* GetIntConstant1();
  HIntConstant* GetIntConstant(int32_t constant);
  HLongConstant* GetLongConstant(int64_t constant);
  void InitializeLocals(uint16_t count);
  HLocal* GetLocalAt(int register_index) const;
  void UpdateLocal(int register_index, HInstruction* instruction) const;
  HInstruction* LoadLocal(int register_index, Primitive::Type type) const;
  void PotentiallyAddSuspendCheck(int32_t target_offset, uint32_t dex_offset);

  // Temporarily returns whether the compiler supports the parameters
  // of the method.
  bool InitializeParameters(uint16_t number_of_parameters);

  template<typename T>
  void Binop_23x(const Instruction& instruction, Primitive::Type type);

  template<typename T>
  void Binop_12x(const Instruction& instruction, Primitive::Type type);

  template<typename T>
  void Binop_22b(const Instruction& instruction, bool reverse);

  template<typename T>
  void Binop_22s(const Instruction& instruction, bool reverse);

  template<typename T> void If_21t(const Instruction& instruction, uint32_t dex_offset);
  template<typename T> void If_22t(const Instruction& instruction, uint32_t dex_offset);

  void BuildReturn(const Instruction& instruction, Primitive::Type type);

  bool BuildFieldAccess(const Instruction& instruction, uint32_t dex_offset, bool is_get);
  void BuildArrayAccess(const Instruction& instruction,
                        uint32_t dex_offset,
                        bool is_get,
                        Primitive::Type anticipated_type);

  // Builds an invocation node and returns whether the instruction is supported.
  bool BuildInvoke(const Instruction& instruction,
                   uint32_t dex_offset,
                   uint32_t method_idx,
                   uint32_t number_of_vreg_arguments,
                   bool is_range,
                   uint32_t* args,
                   uint32_t register_index);

  ArenaAllocator* const arena_;

  // A list of the size of the dex code holding block information for
  // the method. If an entry contains a block, then the dex instruction
  // starting at that entry is the first instruction of a new block.
  GrowableArray<HBasicBlock*> branch_targets_;

  GrowableArray<HLocal*> locals_;

  HBasicBlock* entry_block_;
  HBasicBlock* exit_block_;
  HBasicBlock* current_block_;
  HGraph* graph_;

  HIntConstant* constant0_;
  HIntConstant* constant1_;

  const DexFile* const dex_file_;
  DexCompilationUnit* const dex_compilation_unit_;
  CompilerDriver* const compiler_driver_;

  DISALLOW_COPY_AND_ASSIGN(HGraphBuilder);
};

}  // namespace art

#endif  // ART_COMPILER_OPTIMIZING_BUILDER_H_