builder.h revision 8d6ae524ed5d2fed1f9e789d6de9764d374afa43
1818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray/*
2818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray * Copyright (C) 2014 The Android Open Source Project
3818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray *
4818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray * Licensed under the Apache License, Version 2.0 (the "License");
5818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray * you may not use this file except in compliance with the License.
6818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray * You may obtain a copy of the License at
7818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray *
8818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray *      http://www.apache.org/licenses/LICENSE-2.0
9818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray *
10818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray * Unless required by applicable law or agreed to in writing, software
11818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray * distributed under the License is distributed on an "AS IS" BASIS,
12818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray * See the License for the specific language governing permissions and
14818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray * limitations under the License.
15818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray */
16818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray
17818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray#ifndef ART_COMPILER_OPTIMIZING_BUILDER_H_
18818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray#define ART_COMPILER_OPTIMIZING_BUILDER_H_
19818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray
203ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray#include "dex_file.h"
217fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray#include "dex_file-inl.h"
22e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray#include "driver/compiler_driver.h"
238ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray#include "driver/dex_compilation_unit.h"
2401bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray#include "primitive.h"
250279ebb3efd653e6bb255470c99d26949c7bcd95Ian Rogers#include "utils/arena_object.h"
26be9a92aa804c0d210f80966b74ef8ed3987f335aNicolas Geoffray#include "utils/growable_array.h"
2720dfc797dc631bf8d655dcf123f46f13332d3074Dave Allison#include "nodes.h"
28818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray
29818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffraynamespace art {
30818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray
31818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffrayclass Instruction;
32818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray
33818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffrayclass HGraphBuilder : public ValueObject {
34818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray public:
358ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray  HGraphBuilder(ArenaAllocator* arena,
367fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray                DexCompilationUnit* dex_compilation_unit,
377fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray                const DexFile* dex_file,
387fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray                CompilerDriver* driver)
39818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray      : arena_(arena),
40be9a92aa804c0d210f80966b74ef8ed3987f335aNicolas Geoffray        branch_targets_(arena, 0),
413ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray        locals_(arena, 0),
42818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray        entry_block_(nullptr),
43818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray        exit_block_(nullptr),
44818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray        current_block_(nullptr),
453ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray        graph_(nullptr),
46bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray        constant0_(nullptr),
478ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray        constant1_(nullptr),
488ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray        dex_file_(dex_file),
49e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray        dex_compilation_unit_(dex_compilation_unit),
507fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray        compiler_driver_(driver),
51a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray        return_type_(Primitive::GetType(dex_compilation_unit_->GetShorty()[0])),
52a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray        code_start_(nullptr),
53a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray        latest_result_(nullptr) {}
547fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray
557fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray  // Only for unit testing.
567fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray  HGraphBuilder(ArenaAllocator* arena, Primitive::Type return_type = Primitive::kPrimInt)
577fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray      : arena_(arena),
587fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray        branch_targets_(arena, 0),
597fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray        locals_(arena, 0),
607fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray        entry_block_(nullptr),
617fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray        exit_block_(nullptr),
627fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray        current_block_(nullptr),
637fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray        graph_(nullptr),
647fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray        constant0_(nullptr),
657fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray        constant1_(nullptr),
667fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray        dex_file_(nullptr),
677fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray        dex_compilation_unit_(nullptr),
687fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray        compiler_driver_(nullptr),
69a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray        return_type_(return_type),
70a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray        code_start_(nullptr),
71a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray        latest_result_(nullptr) {}
72818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray
733ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray  HGraph* BuildGraph(const DexFile::CodeItem& code);
74818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray
75818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray private:
76818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray  // Analyzes the dex instruction and adds HInstruction to the graph
77818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray  // to execute that instruction. Returns whether the instruction can
78818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray  // be handled.
79fbc695f9b8e2084697e19c1355ab925f99f0d235Nicolas Geoffray  bool AnalyzeDexInstruction(const Instruction& instruction, uint32_t dex_offset);
80be9a92aa804c0d210f80966b74ef8ed3987f335aNicolas Geoffray
81be9a92aa804c0d210f80966b74ef8ed3987f335aNicolas Geoffray  // Finds all instructions that start a new block, and populates branch_targets_ with
82be9a92aa804c0d210f80966b74ef8ed3987f335aNicolas Geoffray  // the newly created blocks.
83be9a92aa804c0d210f80966b74ef8ed3987f335aNicolas Geoffray  void ComputeBranchTargets(const uint16_t* start, const uint16_t* end);
84be9a92aa804c0d210f80966b74ef8ed3987f335aNicolas Geoffray  void MaybeUpdateCurrentBlock(size_t index);
85be9a92aa804c0d210f80966b74ef8ed3987f335aNicolas Geoffray  HBasicBlock* FindBlockStartingAt(int32_t index) const;
86818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray
8701bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray  HIntConstant* GetIntConstant0();
8801bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray  HIntConstant* GetIntConstant1();
8901bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray  HIntConstant* GetIntConstant(int32_t constant);
9001bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray  HLongConstant* GetLongConstant(int64_t constant);
91f583e5976e1de9aa206fb8de4f91000180685066Nicolas Geoffray  void InitializeLocals(uint16_t count);
923ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray  HLocal* GetLocalAt(int register_index) const;
933ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray  void UpdateLocal(int register_index, HInstruction* instruction) const;
9401bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray  HInstruction* LoadLocal(int register_index, Primitive::Type type) const;
95fbc695f9b8e2084697e19c1355ab925f99f0d235Nicolas Geoffray  void PotentiallyAddSuspendCheck(int32_t target_offset, uint32_t dex_offset);
963ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray
97f583e5976e1de9aa206fb8de4f91000180685066Nicolas Geoffray  // Temporarily returns whether the compiler supports the parameters
98f583e5976e1de9aa206fb8de4f91000180685066Nicolas Geoffray  // of the method.
99f583e5976e1de9aa206fb8de4f91000180685066Nicolas Geoffray  bool InitializeParameters(uint16_t number_of_parameters);
100f583e5976e1de9aa206fb8de4f91000180685066Nicolas Geoffray
10101bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray  template<typename T>
10288cb1755e1d6acaed0f66ce65d7a2a4465053342Roland Levillain  void Unop_12x(const Instruction& instruction, Primitive::Type type);
10388cb1755e1d6acaed0f66ce65d7a2a4465053342Roland Levillain
10488cb1755e1d6acaed0f66ce65d7a2a4465053342Roland Levillain  template<typename T>
105412f10cfed002ab617c78f2621d68446ca4dd8bdNicolas Geoffray  void Binop_23x(const Instruction& instruction, Primitive::Type type);
10601bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray
10701bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray  template<typename T>
10801bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray  void Binop_12x(const Instruction& instruction, Primitive::Type type);
10901bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray
11001bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray  template<typename T>
11101bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray  void Binop_22b(const Instruction& instruction, bool reverse);
11201bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray
11301bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray  template<typename T>
11401bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray  void Binop_22s(const Instruction& instruction, bool reverse);
11501bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray
116e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray  template<typename T> void If_21t(const Instruction& instruction, uint32_t dex_offset);
117e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray  template<typename T> void If_22t(const Instruction& instruction, uint32_t dex_offset);
118f583e5976e1de9aa206fb8de4f91000180685066Nicolas Geoffray
11901bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray  void BuildReturn(const Instruction& instruction, Primitive::Type type);
12001bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray
121e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray  bool BuildFieldAccess(const Instruction& instruction, uint32_t dex_offset, bool is_get);
1223c7bb98698f77af10372cf31824d3bb115d9bf0fNicolas Geoffray  void BuildArrayAccess(const Instruction& instruction,
1233c7bb98698f77af10372cf31824d3bb115d9bf0fNicolas Geoffray                        uint32_t dex_offset,
1243c7bb98698f77af10372cf31824d3bb115d9bf0fNicolas Geoffray                        bool is_get,
1253c7bb98698f77af10372cf31824d3bb115d9bf0fNicolas Geoffray                        Primitive::Type anticipated_type);
126e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray
12701bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray  // Builds an invocation node and returns whether the instruction is supported.
12801bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray  bool BuildInvoke(const Instruction& instruction,
12901bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray                   uint32_t dex_offset,
13001bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray                   uint32_t method_idx,
13101bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray                   uint32_t number_of_vreg_arguments,
13201bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray                   bool is_range,
13301bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray                   uint32_t* args,
13401bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray                   uint32_t register_index);
13501bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray
136a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray  // Builds a new array node and the instructions that fill it.
137a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray  void BuildFilledNewArray(uint32_t dex_offset,
138a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray                           uint32_t type_index,
139a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray                           uint32_t number_of_vreg_arguments,
140a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray                           bool is_range,
141a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray                           uint32_t* args,
142a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray                           uint32_t register_index);
143a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray
144a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray  // Fills the given object with data as specified in the fill-array-data
145a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray  // instruction. Currently only used for non-reference and non-floating point
146a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray  // arrays.
147a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray  template <typename T>
148a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray  void BuildFillArrayData(HInstruction* object,
149a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray                          const T* data,
150a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray                          uint32_t element_count,
151a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray                          Primitive::Type anticipated_type,
152a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray                          uint32_t dex_offset);
153a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray
154a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray  // Fills the given object with data as specified in the fill-array-data
155a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray  // instruction. The data must be for long and double arrays.
156a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray  void BuildFillWideArrayData(HInstruction* object,
1578d6ae524ed5d2fed1f9e789d6de9764d374afa43Nicolas Geoffray                              const int64_t* data,
158a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray                              uint32_t element_count,
159a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray                              uint32_t dex_offset);
160a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray
161818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray  ArenaAllocator* const arena_;
162be9a92aa804c0d210f80966b74ef8ed3987f335aNicolas Geoffray
163be9a92aa804c0d210f80966b74ef8ed3987f335aNicolas Geoffray  // A list of the size of the dex code holding block information for
164be9a92aa804c0d210f80966b74ef8ed3987f335aNicolas Geoffray  // the method. If an entry contains a block, then the dex instruction
165be9a92aa804c0d210f80966b74ef8ed3987f335aNicolas Geoffray  // starting at that entry is the first instruction of a new block.
166be9a92aa804c0d210f80966b74ef8ed3987f335aNicolas Geoffray  GrowableArray<HBasicBlock*> branch_targets_;
167be9a92aa804c0d210f80966b74ef8ed3987f335aNicolas Geoffray
1683ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray  GrowableArray<HLocal*> locals_;
1693ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray
170818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray  HBasicBlock* entry_block_;
171818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray  HBasicBlock* exit_block_;
172818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray  HBasicBlock* current_block_;
173818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray  HGraph* graph_;
174818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray
1753ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray  HIntConstant* constant0_;
176bab4ed7057799a4fadc6283108ab56f389d117d4Nicolas Geoffray  HIntConstant* constant1_;
1773ff386aafefd5282bb76c8a50506a70a4321e698Nicolas Geoffray
1788ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray  const DexFile* const dex_file_;
17901bc96d007b67fdb7fe349232a83e4b354ce3d08Nicolas Geoffray  DexCompilationUnit* const dex_compilation_unit_;
180e50383288a75244255d3ecedcc79ffe9caf774cbNicolas Geoffray  CompilerDriver* const compiler_driver_;
1817fb49da8ec62e8a10ed9419ade9f32c6b1174687Nicolas Geoffray  const Primitive::Type return_type_;
1828ccc3f5d06fd217cdaabd37e743adab2031d3720Nicolas Geoffray
183a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray  // The pointer in the dex file where the instructions of the code item
184a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray  // being currently compiled start.
185a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray  const uint16_t* code_start_;
186a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray
187a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray  // The last invoke or fill-new-array being built. Only to be
188a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray  // used by move-result instructions.
189a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray  HInstruction* latest_result_;
190a3d05a40de076aabf12ea284c67c99ff28b43dbfNicolas Geoffray
191818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray  DISALLOW_COPY_AND_ASSIGN(HGraphBuilder);
192818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray};
193818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray
194818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray}  // namespace art
195818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray
196818f2107e6d2d9e80faac8ae8c92faffa83cbd11Nicolas Geoffray#endif  // ART_COMPILER_OPTIMIZING_BUILDER_H_
197