blob: 581c1d56f229a475dffb3438c0b2243c6fb66abc [file] [log] [blame]
Nicolas Geoffray818f2102014-02-18 16:43:35 +00001/*
2 * Copyright (C) 2014 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_NODES_H_
18#define ART_COMPILER_OPTIMIZING_NODES_H_
19
20#include "utils/allocation.h"
Nicolas Geoffray0e336432014-02-26 18:24:38 +000021#include "utils/arena_bit_vector.h"
Nicolas Geoffray818f2102014-02-18 16:43:35 +000022#include "utils/growable_array.h"
23
24namespace art {
25
26class HBasicBlock;
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +010027class HEnvironment;
Nicolas Geoffray818f2102014-02-18 16:43:35 +000028class HInstruction;
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000029class HIntConstant;
Nicolas Geoffray818f2102014-02-18 16:43:35 +000030class HGraphVisitor;
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +010031class HPhi;
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +000032class LocationSummary;
Nicolas Geoffray818f2102014-02-18 16:43:35 +000033
34static const int kDefaultNumberOfBlocks = 8;
35static const int kDefaultNumberOfSuccessors = 2;
36static const int kDefaultNumberOfPredecessors = 2;
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000037static const int kDefaultNumberOfBackEdges = 1;
Nicolas Geoffray818f2102014-02-18 16:43:35 +000038
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +010039class HInstructionList {
40 public:
41 HInstructionList() : first_instruction_(nullptr), last_instruction_(nullptr) {}
42
43 void AddInstruction(HInstruction* instruction);
44 void RemoveInstruction(HInstruction* instruction);
45
46 private:
47 HInstruction* first_instruction_;
48 HInstruction* last_instruction_;
49
50 friend class HBasicBlock;
51 friend class HInstructionIterator;
52
53 DISALLOW_COPY_AND_ASSIGN(HInstructionList);
54};
55
Nicolas Geoffray818f2102014-02-18 16:43:35 +000056// Control-flow graph of a method. Contains a list of basic blocks.
57class HGraph : public ArenaObject {
58 public:
59 explicit HGraph(ArenaAllocator* arena)
60 : arena_(arena),
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000061 blocks_(arena, kDefaultNumberOfBlocks),
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000062 dominator_order_(arena, kDefaultNumberOfBlocks),
Nicolas Geoffray4a34a422014-04-03 10:38:37 +010063 maximum_number_of_out_vregs_(0),
Nicolas Geoffrayf583e592014-04-07 13:20:42 +010064 number_of_vregs_(0),
65 number_of_in_vregs_(0),
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000066 current_instruction_id_(0) { }
Nicolas Geoffray818f2102014-02-18 16:43:35 +000067
Nicolas Geoffray787c3072014-03-17 10:20:19 +000068 ArenaAllocator* GetArena() const { return arena_; }
69 const GrowableArray<HBasicBlock*>* GetBlocks() const { return &blocks_; }
Nicolas Geoffray818f2102014-02-18 16:43:35 +000070
Nicolas Geoffray787c3072014-03-17 10:20:19 +000071 HBasicBlock* GetEntryBlock() const { return entry_block_; }
72 HBasicBlock* GetExitBlock() const { return exit_block_; }
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +000073
Nicolas Geoffray787c3072014-03-17 10:20:19 +000074 void SetEntryBlock(HBasicBlock* block) { entry_block_ = block; }
75 void SetExitBlock(HBasicBlock* block) { exit_block_ = block; }
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +000076
Nicolas Geoffray818f2102014-02-18 16:43:35 +000077 void AddBlock(HBasicBlock* block);
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +010078
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000079 void BuildDominatorTree();
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +010080 void TransformToSSA();
81 void SimplifyCFG();
Nicolas Geoffray818f2102014-02-18 16:43:35 +000082
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000083 int GetNextInstructionId() {
84 return current_instruction_id_++;
85 }
86
Nicolas Geoffray4a34a422014-04-03 10:38:37 +010087 uint16_t GetMaximumNumberOfOutVRegs() const {
88 return maximum_number_of_out_vregs_;
89 }
90
91 void UpdateMaximumNumberOfOutVRegs(uint16_t new_value) {
92 maximum_number_of_out_vregs_ = std::max(new_value, maximum_number_of_out_vregs_);
93 }
94
Nicolas Geoffrayf583e592014-04-07 13:20:42 +010095 void SetNumberOfVRegs(uint16_t number_of_vregs) {
96 number_of_vregs_ = number_of_vregs;
97 }
98
99 uint16_t GetNumberOfVRegs() const {
100 return number_of_vregs_;
101 }
102
103 void SetNumberOfInVRegs(uint16_t value) {
104 number_of_in_vregs_ = value;
105 }
106
107 uint16_t GetNumberOfInVRegs() const {
108 return number_of_in_vregs_;
109 }
110
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100111 GrowableArray<HBasicBlock*>* GetDominatorOrder() {
112 return &dominator_order_;
113 }
Nicolas Geoffrayf583e592014-04-07 13:20:42 +0100114
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000115 private:
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000116 HBasicBlock* FindCommonDominator(HBasicBlock* first, HBasicBlock* second) const;
117 void VisitBlockForDominatorTree(HBasicBlock* block,
118 HBasicBlock* predecessor,
119 GrowableArray<size_t>* visits);
120 void FindBackEdges(ArenaBitVector* visited) const;
121 void VisitBlockForBackEdges(HBasicBlock* block,
122 ArenaBitVector* visited,
123 ArenaBitVector* visiting) const;
124 void RemoveDeadBlocks(const ArenaBitVector& visited) const;
125
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000126 ArenaAllocator* const arena_;
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000127
128 // List of blocks in insertion order.
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000129 GrowableArray<HBasicBlock*> blocks_;
130
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000131 // List of blocks to perform a pre-order dominator tree traversal.
132 GrowableArray<HBasicBlock*> dominator_order_;
133
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +0000134 HBasicBlock* entry_block_;
135 HBasicBlock* exit_block_;
136
Nicolas Geoffrayf583e592014-04-07 13:20:42 +0100137 // The maximum number of virtual registers arguments passed to a HInvoke in this graph.
Nicolas Geoffray4a34a422014-04-03 10:38:37 +0100138 uint16_t maximum_number_of_out_vregs_;
139
Nicolas Geoffrayf583e592014-04-07 13:20:42 +0100140 // The number of virtual registers in this method. Contains the parameters.
141 uint16_t number_of_vregs_;
142
143 // The number of virtual registers used by parameters of this method.
144 uint16_t number_of_in_vregs_;
145
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000146 // The current id to assign to a newly added instruction. See HInstruction.id_.
147 int current_instruction_id_;
148
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000149 DISALLOW_COPY_AND_ASSIGN(HGraph);
150};
151
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000152class HLoopInformation : public ArenaObject {
153 public:
154 HLoopInformation(HBasicBlock* header, HGraph* graph)
155 : header_(header),
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000156 back_edges_(graph->GetArena(), kDefaultNumberOfBackEdges) { }
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000157
158 void AddBackEdge(HBasicBlock* back_edge) {
159 back_edges_.Add(back_edge);
160 }
161
162 int NumberOfBackEdges() const {
163 return back_edges_.Size();
164 }
165
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100166 void SetPreHeader(HBasicBlock* block);
167
168 HBasicBlock* GetPreHeader() const {
169 return pre_header_;
170 }
171
172 const GrowableArray<HBasicBlock*>* GetBackEdges() const {
173 return &back_edges_;
174 }
175
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000176 private:
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100177 HBasicBlock* pre_header_;
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000178 HBasicBlock* header_;
179 GrowableArray<HBasicBlock*> back_edges_;
180
181 DISALLOW_COPY_AND_ASSIGN(HLoopInformation);
182};
183
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000184// A block in a method. Contains the list of instructions represented
185// as a double linked list. Each block knows its predecessors and
186// successors.
187class HBasicBlock : public ArenaObject {
188 public:
189 explicit HBasicBlock(HGraph* graph)
190 : graph_(graph),
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000191 predecessors_(graph->GetArena(), kDefaultNumberOfPredecessors),
192 successors_(graph->GetArena(), kDefaultNumberOfSuccessors),
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000193 loop_information_(nullptr),
194 dominator_(nullptr),
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000195 block_id_(-1) { }
196
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000197 const GrowableArray<HBasicBlock*>* GetPredecessors() const {
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000198 return &predecessors_;
199 }
200
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000201 const GrowableArray<HBasicBlock*>* GetSuccessors() const {
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000202 return &successors_;
203 }
204
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000205 void AddBackEdge(HBasicBlock* back_edge) {
206 if (loop_information_ == nullptr) {
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000207 loop_information_ = new (graph_->GetArena()) HLoopInformation(this, graph_);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000208 }
209 loop_information_->AddBackEdge(back_edge);
210 }
211
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000212 HGraph* GetGraph() const { return graph_; }
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000213
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000214 int GetBlockId() const { return block_id_; }
215 void SetBlockId(int id) { block_id_ = id; }
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000216
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000217 HBasicBlock* GetDominator() const { return dominator_; }
218 void SetDominator(HBasicBlock* dominator) { dominator_ = dominator; }
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000219
220 int NumberOfBackEdges() const {
221 return loop_information_ == nullptr
222 ? 0
223 : loop_information_->NumberOfBackEdges();
224 }
225
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100226 HInstruction* GetFirstInstruction() const { return instructions_.first_instruction_; }
227 HInstruction* GetLastInstruction() const { return instructions_.last_instruction_; }
228 HInstructionList const* GetInstructions() const { return &instructions_; }
229 HInstructionList const* GetPhis() const { return &phis_; }
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000230
231 void AddSuccessor(HBasicBlock* block) {
232 successors_.Add(block);
233 block->predecessors_.Add(this);
234 }
235
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100236 void RemovePredecessor(HBasicBlock* block, bool remove_in_successor = true) {
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000237 predecessors_.Delete(block);
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100238 if (remove_in_successor) {
239 block->successors_.Delete(this);
240 }
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000241 }
242
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000243 void AddInstruction(HInstruction* instruction);
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100244 void RemoveInstruction(HInstruction* instruction);
245 void AddPhi(HPhi* phi);
246 void RemovePhi(HPhi* phi);
247
248 bool IsLoopHeader() const {
249 return loop_information_ != nullptr;
250 }
251
252 HLoopInformation* GetLoopInformation() const {
253 return loop_information_;
254 }
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000255
256 private:
257 HGraph* const graph_;
258 GrowableArray<HBasicBlock*> predecessors_;
259 GrowableArray<HBasicBlock*> successors_;
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100260 HInstructionList instructions_;
261 HInstructionList phis_;
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000262 HLoopInformation* loop_information_;
263 HBasicBlock* dominator_;
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000264 int block_id_;
265
266 DISALLOW_COPY_AND_ASSIGN(HBasicBlock);
267};
268
269#define FOR_EACH_INSTRUCTION(M) \
Nicolas Geoffrayd8ee7372014-03-28 15:43:40 +0000270 M(Add) \
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000271 M(Equal) \
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000272 M(Exit) \
273 M(Goto) \
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000274 M(If) \
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000275 M(IntConstant) \
Nicolas Geoffray8ccc3f52014-03-19 10:34:11 +0000276 M(InvokeStatic) \
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000277 M(LoadLocal) \
278 M(Local) \
Nicolas Geoffray01bc96d2014-04-11 17:43:50 +0100279 M(LongConstant) \
Nicolas Geoffray2e7038a2014-04-03 18:49:58 +0100280 M(NewInstance) \
Nicolas Geoffrayb55f8352014-04-07 15:26:35 +0100281 M(Not) \
Nicolas Geoffrayf583e592014-04-07 13:20:42 +0100282 M(ParameterValue) \
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100283 M(Phi) \
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +0000284 M(Return) \
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000285 M(ReturnVoid) \
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000286 M(StoreLocal) \
Nicolas Geoffrayf583e592014-04-07 13:20:42 +0100287 M(Sub) \
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000288
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +0000289#define FORWARD_DECLARATION(type) class H##type;
290FOR_EACH_INSTRUCTION(FORWARD_DECLARATION)
291#undef FORWARD_DECLARATION
292
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000293#define DECLARE_INSTRUCTION(type) \
294 virtual void Accept(HGraphVisitor* visitor); \
295 virtual const char* DebugName() const { return #type; } \
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +0000296 virtual H##type* As##type() { return this; } \
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000297
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100298template <typename T>
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000299class HUseListNode : public ArenaObject {
300 public:
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100301 HUseListNode(T* user, size_t index, HUseListNode* tail)
302 : user_(user), index_(index), tail_(tail) { }
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000303
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000304 HUseListNode* GetTail() const { return tail_; }
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100305 T* GetUser() const { return user_; }
306 size_t GetIndex() const { return index_; }
307
308 void SetTail(HUseListNode<T>* node) { tail_ = node; }
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000309
310 private:
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100311 T* const user_;
312 const size_t index_;
313 HUseListNode<T>* tail_;
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000314
315 DISALLOW_COPY_AND_ASSIGN(HUseListNode);
316};
317
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000318class HInstruction : public ArenaObject {
319 public:
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +0000320 HInstruction()
321 : previous_(nullptr),
322 next_(nullptr),
323 block_(nullptr),
324 id_(-1),
325 uses_(nullptr),
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100326 env_uses_(nullptr),
327 environment_(nullptr),
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +0000328 locations_(nullptr) { }
329
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000330 virtual ~HInstruction() { }
331
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000332 HInstruction* GetNext() const { return next_; }
333 HInstruction* GetPrevious() const { return previous_; }
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000334
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000335 HBasicBlock* GetBlock() const { return block_; }
336 void SetBlock(HBasicBlock* block) { block_ = block; }
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +0000337
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100338 virtual size_t InputCount() const = 0;
339 virtual HInstruction* InputAt(size_t i) const = 0;
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000340
341 virtual void Accept(HGraphVisitor* visitor) = 0;
342 virtual const char* DebugName() const = 0;
343
Nicolas Geoffray01bc96d2014-04-11 17:43:50 +0100344 virtual Primitive::Type GetType() const { return Primitive::kPrimVoid; }
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100345 virtual void SetRawInputAt(size_t index, HInstruction* input) = 0;
Nicolas Geoffray01bc96d2014-04-11 17:43:50 +0100346
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100347 virtual bool NeedsEnvironment() const { return false; }
348
349 void AddUseAt(HInstruction* user, size_t index) {
350 uses_ = new (block_->GetGraph()->GetArena()) HUseListNode<HInstruction>(user, index, uses_);
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000351 }
352
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100353 void AddEnvUseAt(HEnvironment* user, size_t index) {
354 env_uses_ = new (block_->GetGraph()->GetArena()) HUseListNode<HEnvironment>(
355 user, index, env_uses_);
356 }
357
358 void RemoveUser(HInstruction* user, size_t index);
359
360 HUseListNode<HInstruction>* GetUses() const { return uses_; }
361 HUseListNode<HEnvironment>* GetEnvUses() const { return env_uses_; }
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000362
363 bool HasUses() const { return uses_ != nullptr; }
364
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000365 int GetId() const { return id_; }
366 void SetId(int id) { id_ = id; }
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000367
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100368 void SetEnvironment(HEnvironment* environment) { environment_ = environment; }
369
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000370 LocationSummary* GetLocations() const { return locations_; }
371 void SetLocations(LocationSummary* locations) { locations_ = locations; }
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +0000372
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100373 void ReplaceWith(HInstruction* instruction);
374
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +0000375#define INSTRUCTION_TYPE_CHECK(type) \
376 virtual H##type* As##type() { return nullptr; }
377
378 FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK)
379#undef INSTRUCTION_TYPE_CHECK
380
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000381 private:
382 HInstruction* previous_;
383 HInstruction* next_;
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +0000384 HBasicBlock* block_;
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000385
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000386 // An instruction gets an id when it is added to the graph.
387 // It reflects creation order. A negative id means the instruction
388 // has not beed added to the graph.
389 int id_;
390
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100391 // List of instructions that have this instruction as input.
392 HUseListNode<HInstruction>* uses_;
393
394 // List of environments that contain this instruction.
395 HUseListNode<HEnvironment>* env_uses_;
396
397 HEnvironment* environment_;
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000398
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +0000399 // Set by the code generator.
400 LocationSummary* locations_;
401
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000402 friend class HBasicBlock;
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100403 friend class HInstructionList;
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000404
405 DISALLOW_COPY_AND_ASSIGN(HInstruction);
406};
407
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100408template<typename T>
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000409class HUseIterator : public ValueObject {
410 public:
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100411 explicit HUseIterator(HUseListNode<T>* uses) : current_(uses) {}
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000412
413 bool Done() const { return current_ == nullptr; }
414
415 void Advance() {
416 DCHECK(!Done());
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000417 current_ = current_->GetTail();
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000418 }
419
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100420 HUseListNode<T>* Current() const {
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000421 DCHECK(!Done());
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100422 return current_;
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000423 }
424
425 private:
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100426 HUseListNode<T>* current_;
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000427
428 friend class HValue;
429};
430
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100431// A HEnvironment object contains the values of virtual registers at a given location.
432class HEnvironment : public ArenaObject {
433 public:
434 HEnvironment(ArenaAllocator* arena, size_t number_of_vregs) : vregs_(arena, number_of_vregs) {
435 vregs_.SetSize(number_of_vregs);
436 for (size_t i = 0; i < number_of_vregs; i++) {
437 vregs_.Put(i, nullptr);
438 }
439 }
440
441 void Populate(const GrowableArray<HInstruction*>& env) {
442 for (size_t i = 0; i < env.Size(); i++) {
443 HInstruction* instruction = env.Get(i);
444 vregs_.Put(i, instruction);
445 if (instruction != nullptr) {
446 instruction->AddEnvUseAt(this, i);
447 }
448 }
449 }
450
451 void SetRawEnvAt(size_t index, HInstruction* instruction) {
452 vregs_.Put(index, instruction);
453 }
454
455 GrowableArray<HInstruction*>* GetVRegs() {
456 return &vregs_;
457 }
458
459 private:
460 GrowableArray<HInstruction*> vregs_;
461
462 DISALLOW_COPY_AND_ASSIGN(HEnvironment);
463};
464
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000465class HInputIterator : public ValueObject {
466 public:
467 explicit HInputIterator(HInstruction* instruction) : instruction_(instruction), index_(0) { }
468
469 bool Done() const { return index_ == instruction_->InputCount(); }
470 HInstruction* Current() const { return instruction_->InputAt(index_); }
471 void Advance() { index_++; }
472
473 private:
474 HInstruction* instruction_;
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100475 size_t index_;
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000476
477 DISALLOW_COPY_AND_ASSIGN(HInputIterator);
478};
479
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000480class HInstructionIterator : public ValueObject {
481 public:
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100482 explicit HInstructionIterator(const HInstructionList& instructions)
483 : instruction_(instructions.first_instruction_) {
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000484 next_ = Done() ? nullptr : instruction_->GetNext();
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000485 }
486
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000487 bool Done() const { return instruction_ == nullptr; }
488 HInstruction* Current() const { return instruction_; }
489 void Advance() {
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000490 instruction_ = next_;
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000491 next_ = Done() ? nullptr : instruction_->GetNext();
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000492 }
493
494 private:
495 HInstruction* instruction_;
496 HInstruction* next_;
497};
498
499// An embedded container with N elements of type T. Used (with partial
500// specialization for N=0) because embedded arrays cannot have size 0.
501template<typename T, intptr_t N>
502class EmbeddedArray {
503 public:
504 EmbeddedArray() : elements_() { }
505
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000506 intptr_t GetLength() const { return N; }
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000507
508 const T& operator[](intptr_t i) const {
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000509 DCHECK_LT(i, GetLength());
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000510 return elements_[i];
511 }
512
513 T& operator[](intptr_t i) {
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000514 DCHECK_LT(i, GetLength());
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000515 return elements_[i];
516 }
517
518 const T& At(intptr_t i) const {
519 return (*this)[i];
520 }
521
522 void SetAt(intptr_t i, const T& val) {
523 (*this)[i] = val;
524 }
525
526 private:
527 T elements_[N];
528};
529
530template<typename T>
531class EmbeddedArray<T, 0> {
532 public:
533 intptr_t length() const { return 0; }
534 const T& operator[](intptr_t i) const {
535 LOG(FATAL) << "Unreachable";
536 static T sentinel = 0;
537 return sentinel;
538 }
539 T& operator[](intptr_t i) {
540 LOG(FATAL) << "Unreachable";
541 static T sentinel = 0;
542 return sentinel;
543 }
544};
545
546template<intptr_t N>
547class HTemplateInstruction: public HInstruction {
548 public:
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000549 HTemplateInstruction<N>() : inputs_() { }
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000550 virtual ~HTemplateInstruction() { }
551
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100552 virtual size_t InputCount() const { return N; }
553 virtual HInstruction* InputAt(size_t i) const { return inputs_[i]; }
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000554
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000555 protected:
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100556 virtual void SetRawInputAt(size_t i, HInstruction* instruction) {
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000557 inputs_[i] = instruction;
558 }
559
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000560 private:
561 EmbeddedArray<HInstruction*, N> inputs_;
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100562
563 friend class SsaBuilder;
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000564};
565
566// Represents dex's RETURN_VOID opcode. A HReturnVoid is a control flow
567// instruction that branches to the exit block.
568class HReturnVoid : public HTemplateInstruction<0> {
569 public:
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000570 HReturnVoid() { }
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000571
572 DECLARE_INSTRUCTION(ReturnVoid)
573
574 private:
575 DISALLOW_COPY_AND_ASSIGN(HReturnVoid);
576};
577
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +0000578// Represents dex's RETURN opcodes. A HReturn is a control flow
579// instruction that branches to the exit block.
580class HReturn : public HTemplateInstruction<1> {
581 public:
582 explicit HReturn(HInstruction* value) {
583 SetRawInputAt(0, value);
584 }
585
586 DECLARE_INSTRUCTION(Return)
587
588 private:
589 DISALLOW_COPY_AND_ASSIGN(HReturn);
590};
591
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000592// The exit instruction is the only instruction of the exit block.
593// Instructions aborting the method (HTrow and HReturn) must branch to the
594// exit block.
595class HExit : public HTemplateInstruction<0> {
596 public:
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000597 HExit() { }
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000598
599 DECLARE_INSTRUCTION(Exit)
600
601 private:
602 DISALLOW_COPY_AND_ASSIGN(HExit);
603};
604
605// Jumps from one block to another.
606class HGoto : public HTemplateInstruction<0> {
607 public:
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000608 HGoto() { }
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000609
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +0000610 HBasicBlock* GetSuccessor() const {
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000611 return GetBlock()->GetSuccessors()->Get(0);
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +0000612 }
613
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000614 DECLARE_INSTRUCTION(Goto)
615
616 private:
617 DISALLOW_COPY_AND_ASSIGN(HGoto);
618};
619
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000620// Conditional branch. A block ending with an HIf instruction must have
621// two successors.
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000622class HIf : public HTemplateInstruction<1> {
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000623 public:
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000624 explicit HIf(HInstruction* input) {
625 SetRawInputAt(0, input);
626 }
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000627
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +0000628 HBasicBlock* IfTrueSuccessor() const {
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000629 return GetBlock()->GetSuccessors()->Get(0);
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +0000630 }
631
632 HBasicBlock* IfFalseSuccessor() const {
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000633 return GetBlock()->GetSuccessors()->Get(1);
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +0000634 }
635
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000636 DECLARE_INSTRUCTION(If)
637
638 private:
639 DISALLOW_COPY_AND_ASSIGN(HIf);
640};
641
Nicolas Geoffrayd8ee7372014-03-28 15:43:40 +0000642class HBinaryOperation : public HTemplateInstruction<2> {
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000643 public:
Nicolas Geoffrayd8ee7372014-03-28 15:43:40 +0000644 HBinaryOperation(Primitive::Type result_type,
645 HInstruction* left,
646 HInstruction* right) : result_type_(result_type) {
647 SetRawInputAt(0, left);
648 SetRawInputAt(1, right);
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000649 }
650
Nicolas Geoffrayd8ee7372014-03-28 15:43:40 +0000651 HInstruction* GetLeft() const { return InputAt(0); }
652 HInstruction* GetRight() const { return InputAt(1); }
653 Primitive::Type GetResultType() const { return result_type_; }
654
655 virtual bool IsCommutative() { return false; }
Nicolas Geoffray01bc96d2014-04-11 17:43:50 +0100656 virtual Primitive::Type GetType() const { return GetResultType(); }
Nicolas Geoffrayd8ee7372014-03-28 15:43:40 +0000657
658 private:
659 const Primitive::Type result_type_;
660
661 DISALLOW_COPY_AND_ASSIGN(HBinaryOperation);
662};
663
664
665// Instruction to check if two inputs are equal to each other.
666class HEqual : public HBinaryOperation {
667 public:
668 HEqual(HInstruction* first, HInstruction* second)
669 : HBinaryOperation(Primitive::kPrimBoolean, first, second) {}
670
671 virtual bool IsCommutative() { return true; }
672
Nicolas Geoffray01bc96d2014-04-11 17:43:50 +0100673 virtual Primitive::Type GetType() const { return Primitive::kPrimBoolean; }
674
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000675 DECLARE_INSTRUCTION(Equal)
676
677 private:
678 DISALLOW_COPY_AND_ASSIGN(HEqual);
679};
680
681// A local in the graph. Corresponds to a Dex register.
682class HLocal : public HTemplateInstruction<0> {
683 public:
684 explicit HLocal(uint16_t reg_number) : reg_number_(reg_number) { }
685
686 DECLARE_INSTRUCTION(Local)
687
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000688 uint16_t GetRegNumber() const { return reg_number_; }
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +0000689
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000690 private:
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +0000691 // The Dex register number.
692 const uint16_t reg_number_;
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000693
694 DISALLOW_COPY_AND_ASSIGN(HLocal);
695};
696
697// Load a given local. The local is an input of this instruction.
698class HLoadLocal : public HTemplateInstruction<1> {
699 public:
Nicolas Geoffray01bc96d2014-04-11 17:43:50 +0100700 explicit HLoadLocal(HLocal* local, Primitive::Type type) : type_(type) {
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000701 SetRawInputAt(0, local);
702 }
703
Nicolas Geoffray01bc96d2014-04-11 17:43:50 +0100704 virtual Primitive::Type GetType() const { return type_; }
705
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +0000706 HLocal* GetLocal() const { return reinterpret_cast<HLocal*>(InputAt(0)); }
707
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000708 DECLARE_INSTRUCTION(LoadLocal)
709
710 private:
Nicolas Geoffray01bc96d2014-04-11 17:43:50 +0100711 const Primitive::Type type_;
712
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000713 DISALLOW_COPY_AND_ASSIGN(HLoadLocal);
714};
715
716// Store a value in a given local. This instruction has two inputs: the value
717// and the local.
718class HStoreLocal : public HTemplateInstruction<2> {
719 public:
720 HStoreLocal(HLocal* local, HInstruction* value) {
721 SetRawInputAt(0, local);
722 SetRawInputAt(1, value);
723 }
724
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +0000725 HLocal* GetLocal() const { return reinterpret_cast<HLocal*>(InputAt(0)); }
726
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000727 DECLARE_INSTRUCTION(StoreLocal)
728
729 private:
730 DISALLOW_COPY_AND_ASSIGN(HStoreLocal);
731};
732
733// Constants of the type int. Those can be from Dex instructions, or
734// synthesized (for example with the if-eqz instruction).
735class HIntConstant : public HTemplateInstruction<0> {
736 public:
737 explicit HIntConstant(int32_t value) : value_(value) { }
738
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000739 int32_t GetValue() const { return value_; }
Nicolas Geoffray01bc96d2014-04-11 17:43:50 +0100740 virtual Primitive::Type GetType() const { return Primitive::kPrimInt; }
Nicolas Geoffraybab4ed72014-03-11 17:53:17 +0000741
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000742 DECLARE_INSTRUCTION(IntConstant)
743
744 private:
745 const int32_t value_;
746
747 DISALLOW_COPY_AND_ASSIGN(HIntConstant);
748};
749
Nicolas Geoffray01bc96d2014-04-11 17:43:50 +0100750class HLongConstant : public HTemplateInstruction<0> {
751 public:
752 explicit HLongConstant(int64_t value) : value_(value) { }
753
754 int64_t GetValue() const { return value_; }
755
756 virtual Primitive::Type GetType() const { return Primitive::kPrimLong; }
757
758 DECLARE_INSTRUCTION(LongConstant)
759
760 private:
761 const int64_t value_;
762
763 DISALLOW_COPY_AND_ASSIGN(HLongConstant);
764};
765
Nicolas Geoffray8ccc3f52014-03-19 10:34:11 +0000766class HInvoke : public HInstruction {
767 public:
Nicolas Geoffray01bc96d2014-04-11 17:43:50 +0100768 HInvoke(ArenaAllocator* arena,
769 uint32_t number_of_arguments,
770 Primitive::Type return_type,
771 uint32_t dex_pc)
Nicolas Geoffray8ccc3f52014-03-19 10:34:11 +0000772 : inputs_(arena, number_of_arguments),
Nicolas Geoffray01bc96d2014-04-11 17:43:50 +0100773 return_type_(return_type),
Nicolas Geoffray8ccc3f52014-03-19 10:34:11 +0000774 dex_pc_(dex_pc) {
775 inputs_.SetSize(number_of_arguments);
776 }
777
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100778 virtual size_t InputCount() const { return inputs_.Size(); }
779 virtual HInstruction* InputAt(size_t i) const { return inputs_.Get(i); }
780
781 // Runtime needs to walk the stack, so Dex -> Dex calls need to
782 // know their environment.
783 virtual bool NeedsEnvironment() const { return true; }
Nicolas Geoffray8ccc3f52014-03-19 10:34:11 +0000784
Nicolas Geoffray4a34a422014-04-03 10:38:37 +0100785 void SetArgumentAt(size_t index, HInstruction* argument) {
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100786 SetRawInputAt(index, argument);
787 }
788
789 virtual void SetRawInputAt(size_t index, HInstruction* input) {
790 inputs_.Put(index, input);
Nicolas Geoffray4a34a422014-04-03 10:38:37 +0100791 }
792
Nicolas Geoffray01bc96d2014-04-11 17:43:50 +0100793 virtual Primitive::Type GetType() const { return return_type_; }
794
Nicolas Geoffray2e7038a2014-04-03 18:49:58 +0100795 uint32_t GetDexPc() const { return dex_pc_; }
Nicolas Geoffray8ccc3f52014-03-19 10:34:11 +0000796
797 protected:
798 GrowableArray<HInstruction*> inputs_;
Nicolas Geoffray01bc96d2014-04-11 17:43:50 +0100799 const Primitive::Type return_type_;
Nicolas Geoffray2e7038a2014-04-03 18:49:58 +0100800 const uint32_t dex_pc_;
Nicolas Geoffray8ccc3f52014-03-19 10:34:11 +0000801
802 private:
803 DISALLOW_COPY_AND_ASSIGN(HInvoke);
804};
805
806class HInvokeStatic : public HInvoke {
807 public:
Nicolas Geoffray4a34a422014-04-03 10:38:37 +0100808 HInvokeStatic(ArenaAllocator* arena,
809 uint32_t number_of_arguments,
Nicolas Geoffray01bc96d2014-04-11 17:43:50 +0100810 Primitive::Type return_type,
Nicolas Geoffray2e7038a2014-04-03 18:49:58 +0100811 uint32_t dex_pc,
812 uint32_t index_in_dex_cache)
Nicolas Geoffray01bc96d2014-04-11 17:43:50 +0100813 : HInvoke(arena, number_of_arguments, return_type, dex_pc),
814 index_in_dex_cache_(index_in_dex_cache) {}
Nicolas Geoffray8ccc3f52014-03-19 10:34:11 +0000815
816 uint32_t GetIndexInDexCache() const { return index_in_dex_cache_; }
817
818 DECLARE_INSTRUCTION(InvokeStatic)
819
820 private:
Nicolas Geoffray4a34a422014-04-03 10:38:37 +0100821 const uint32_t index_in_dex_cache_;
Nicolas Geoffray8ccc3f52014-03-19 10:34:11 +0000822
823 DISALLOW_COPY_AND_ASSIGN(HInvokeStatic);
824};
825
Nicolas Geoffray2e7038a2014-04-03 18:49:58 +0100826class HNewInstance : public HTemplateInstruction<0> {
827 public:
828 HNewInstance(uint32_t dex_pc, uint16_t type_index) : dex_pc_(dex_pc), type_index_(type_index) {}
829
830 uint32_t GetDexPc() const { return dex_pc_; }
831 uint16_t GetTypeIndex() const { return type_index_; }
832
Nicolas Geoffray01bc96d2014-04-11 17:43:50 +0100833 virtual Primitive::Type GetType() const { return Primitive::kPrimNot; }
834
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100835 // Calls runtime so needs an environment.
836 virtual bool NeedsEnvironment() const { return true; }
837
Nicolas Geoffray2e7038a2014-04-03 18:49:58 +0100838 DECLARE_INSTRUCTION(NewInstance)
839
840 private:
841 const uint32_t dex_pc_;
842 const uint16_t type_index_;
843
844 DISALLOW_COPY_AND_ASSIGN(HNewInstance);
845};
846
Nicolas Geoffrayd8ee7372014-03-28 15:43:40 +0000847class HAdd : public HBinaryOperation {
848 public:
849 HAdd(Primitive::Type result_type, HInstruction* left, HInstruction* right)
850 : HBinaryOperation(result_type, left, right) {}
851
852 virtual bool IsCommutative() { return true; }
853
854 DECLARE_INSTRUCTION(Add);
855
856 private:
857 DISALLOW_COPY_AND_ASSIGN(HAdd);
858};
859
Nicolas Geoffrayf583e592014-04-07 13:20:42 +0100860class HSub : public HBinaryOperation {
861 public:
862 HSub(Primitive::Type result_type, HInstruction* left, HInstruction* right)
863 : HBinaryOperation(result_type, left, right) {}
864
865 virtual bool IsCommutative() { return false; }
866
867 DECLARE_INSTRUCTION(Sub);
868
869 private:
870 DISALLOW_COPY_AND_ASSIGN(HSub);
871};
872
873// The value of a parameter in this method. Its location depends on
874// the calling convention.
875class HParameterValue : public HTemplateInstruction<0> {
876 public:
Nicolas Geoffray01bc96d2014-04-11 17:43:50 +0100877 HParameterValue(uint8_t index, Primitive::Type parameter_type)
878 : index_(index), parameter_type_(parameter_type) {}
Nicolas Geoffrayf583e592014-04-07 13:20:42 +0100879
880 uint8_t GetIndex() const { return index_; }
881
Nicolas Geoffray01bc96d2014-04-11 17:43:50 +0100882 virtual Primitive::Type GetType() const { return parameter_type_; }
883
Nicolas Geoffrayf583e592014-04-07 13:20:42 +0100884 DECLARE_INSTRUCTION(ParameterValue);
885
886 private:
887 // The index of this parameter in the parameters list. Must be less
888 // than HGraph::number_of_in_vregs_;
889 const uint8_t index_;
890
Nicolas Geoffray01bc96d2014-04-11 17:43:50 +0100891 const Primitive::Type parameter_type_;
892
Nicolas Geoffrayf583e592014-04-07 13:20:42 +0100893 DISALLOW_COPY_AND_ASSIGN(HParameterValue);
894};
895
Nicolas Geoffrayb55f8352014-04-07 15:26:35 +0100896class HNot : public HTemplateInstruction<1> {
897 public:
898 explicit HNot(HInstruction* input) {
899 SetRawInputAt(0, input);
900 }
901
Nicolas Geoffray01bc96d2014-04-11 17:43:50 +0100902 virtual Primitive::Type GetType() const { return Primitive::kPrimBoolean; }
903
Nicolas Geoffrayb55f8352014-04-07 15:26:35 +0100904 DECLARE_INSTRUCTION(Not);
905
906 private:
907 DISALLOW_COPY_AND_ASSIGN(HNot);
908};
909
Nicolas Geoffrayc32e7702014-04-24 12:43:16 +0100910class HPhi : public HInstruction {
911 public:
912 HPhi(ArenaAllocator* arena, uint32_t reg_number, size_t number_of_inputs, Primitive::Type type)
913 : inputs_(arena, number_of_inputs),
914 reg_number_(reg_number),
915 type_(type) {
916 inputs_.SetSize(number_of_inputs);
917 }
918
919 virtual size_t InputCount() const { return inputs_.Size(); }
920 virtual HInstruction* InputAt(size_t i) const { return inputs_.Get(i); }
921
922 virtual void SetRawInputAt(size_t index, HInstruction* input) {
923 inputs_.Put(index, input);
924 }
925
926 void AddInput(HInstruction* input);
927
928 virtual Primitive::Type GetType() const { return type_; }
929
930 uint32_t GetRegNumber() const { return reg_number_; }
931
932 DECLARE_INSTRUCTION(Phi)
933
934 protected:
935 GrowableArray<HInstruction*> inputs_;
936 const uint32_t reg_number_;
937 const Primitive::Type type_;
938
939 private:
940 DISALLOW_COPY_AND_ASSIGN(HPhi);
941};
942
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000943class HGraphVisitor : public ValueObject {
944 public:
945 explicit HGraphVisitor(HGraph* graph) : graph_(graph) { }
946 virtual ~HGraphVisitor() { }
947
948 virtual void VisitInstruction(HInstruction* instruction) { }
949 virtual void VisitBasicBlock(HBasicBlock* block);
950
951 void VisitInsertionOrder();
952
Nicolas Geoffray787c3072014-03-17 10:20:19 +0000953 HGraph* GetGraph() const { return graph_; }
Nicolas Geoffrayd4dd2552014-02-28 10:23:58 +0000954
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000955 // Visit functions for instruction classes.
956#define DECLARE_VISIT_INSTRUCTION(name) \
957 virtual void Visit##name(H##name* instr) { VisitInstruction(instr); }
958
959 FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION)
960
961#undef DECLARE_VISIT_INSTRUCTION
962
963 private:
964 HGraph* graph_;
965
966 DISALLOW_COPY_AND_ASSIGN(HGraphVisitor);
967};
968
969} // namespace art
970
971#endif // ART_COMPILER_OPTIMIZING_NODES_H_