summaryrefslogtreecommitdiffstats
path: root/compiler/optimizing/nodes.h
diff options
context:
space:
mode:
authorNicolas Geoffray <ngeoffray@google.com>2014-03-04 14:46:47 +0000
committerNicolas Geoffray <ngeoffray@google.com>2014-03-10 11:41:22 +0000
commit3ff386aafefd5282bb76c8a50506a70a4321e698 (patch)
tree5f6e990553daae150a168f581bac79e659f7f712 /compiler/optimizing/nodes.h
parent0307b5c91c287e08cd414ecc5de32befceb7e371 (diff)
downloadart-3ff386aafefd5282bb76c8a50506a70a4321e698.zip
art-3ff386aafefd5282bb76c8a50506a70a4321e698.tar.gz
art-3ff386aafefd5282bb76c8a50506a70a4321e698.tar.bz2
Add register support to the optimizing compiler.
Also make if take an input and build the use list for instructions. Change-Id: I1938cee7dce5bd4c66b259fa2b431d2c79b3cf82
Diffstat (limited to 'compiler/optimizing/nodes.h')
-rw-r--r--compiler/optimizing/nodes.h181
1 files changed, 170 insertions, 11 deletions
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 46fe95e..bb08bd0 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -25,6 +25,7 @@ namespace art {
class HBasicBlock;
class HInstruction;
+class HIntConstant;
class HGraphVisitor;
static const int kDefaultNumberOfBlocks = 8;
@@ -38,7 +39,8 @@ class HGraph : public ArenaObject {
explicit HGraph(ArenaAllocator* arena)
: arena_(arena),
blocks_(arena, kDefaultNumberOfBlocks),
- dominator_order_(arena, kDefaultNumberOfBlocks) { }
+ dominator_order_(arena, kDefaultNumberOfBlocks),
+ current_instruction_id_(0) { }
ArenaAllocator* arena() const { return arena_; }
const GrowableArray<HBasicBlock*>* blocks() const { return &blocks_; }
@@ -49,10 +51,13 @@ class HGraph : public ArenaObject {
void set_entry_block(HBasicBlock* block) { entry_block_ = block; }
void set_exit_block(HBasicBlock* block) { exit_block_ = block; }
-
void AddBlock(HBasicBlock* block);
void BuildDominatorTree();
+ int GetNextInstructionId() {
+ return current_instruction_id_++;
+ }
+
private:
HBasicBlock* FindCommonDominator(HBasicBlock* first, HBasicBlock* second) const;
void VisitBlockForDominatorTree(HBasicBlock* block,
@@ -75,6 +80,9 @@ class HGraph : public ArenaObject {
HBasicBlock* entry_block_;
HBasicBlock* exit_block_;
+ // The current id to assign to a newly added instruction. See HInstruction.id_.
+ int current_instruction_id_;
+
DISALLOW_COPY_AND_ASSIGN(HGraph);
};
@@ -171,18 +179,38 @@ class HBasicBlock : public ArenaObject {
};
#define FOR_EACH_INSTRUCTION(M) \
+ M(Equal) \
M(Exit) \
M(Goto) \
M(If) \
+ M(IntConstant) \
+ M(LoadLocal) \
+ M(Local) \
M(ReturnVoid) \
+ M(StoreLocal) \
#define DECLARE_INSTRUCTION(type) \
virtual void Accept(HGraphVisitor* visitor); \
virtual const char* DebugName() const { return #type; } \
+class HUseListNode : public ArenaObject {
+ public:
+ HUseListNode(HInstruction* instruction, HUseListNode* tail)
+ : instruction_(instruction), tail_(tail) { }
+
+ HUseListNode* tail() const { return tail_; }
+ HInstruction* instruction() const { return instruction_; }
+
+ private:
+ HInstruction* const instruction_;
+ HUseListNode* const tail_;
+
+ DISALLOW_COPY_AND_ASSIGN(HUseListNode);
+};
+
class HInstruction : public ArenaObject {
public:
- HInstruction() : previous_(nullptr), next_(nullptr), block_(nullptr) { }
+ HInstruction() : previous_(nullptr), next_(nullptr), block_(nullptr), id_(-1), uses_(nullptr) { }
virtual ~HInstruction() { }
HInstruction* next() const { return next_; }
@@ -197,16 +225,71 @@ class HInstruction : public ArenaObject {
virtual void Accept(HGraphVisitor* visitor) = 0;
virtual const char* DebugName() const = 0;
+ void AddUse(HInstruction* user) {
+ uses_ = new (block_->graph()->arena()) HUseListNode(user, uses_);
+ }
+
+ HUseListNode* uses() const { return uses_; }
+
+ bool HasUses() const { return uses_ != nullptr; }
+
+ int id() const { return id_; }
+ void set_id(int id) { id_ = id; }
+
private:
HInstruction* previous_;
HInstruction* next_;
HBasicBlock* block_;
+ // An instruction gets an id when it is added to the graph.
+ // It reflects creation order. A negative id means the instruction
+ // has not beed added to the graph.
+ int id_;
+
+ HUseListNode* uses_;
+
friend class HBasicBlock;
DISALLOW_COPY_AND_ASSIGN(HInstruction);
};
+class HUseIterator : public ValueObject {
+ public:
+ explicit HUseIterator(HInstruction* instruction) : current_(instruction->uses()) { }
+
+ bool Done() const { return current_ == nullptr; }
+
+ void Advance() {
+ DCHECK(!Done());
+ current_ = current_->tail();
+ }
+
+ HInstruction* Current() const {
+ DCHECK(!Done());
+ return current_->instruction();
+ }
+
+ private:
+ HUseListNode* current_;
+
+ friend class HValue;
+};
+
+class HInputIterator : public ValueObject {
+ public:
+ explicit HInputIterator(HInstruction* instruction) : instruction_(instruction), index_(0) { }
+
+ bool Done() const { return index_ == instruction_->InputCount(); }
+ HInstruction* Current() const { return instruction_->InputAt(index_); }
+ void Advance() { index_++; }
+
+ private:
+ HInstruction* instruction_;
+ int index_;
+
+ DISALLOW_COPY_AND_ASSIGN(HInputIterator);
+};
+
class HInstructionIterator : public ValueObject {
public:
explicit HInstructionIterator(HBasicBlock* block)
@@ -214,9 +297,9 @@ class HInstructionIterator : public ValueObject {
next_ = Done() ? nullptr : instruction_->next();
}
- inline bool Done() const { return instruction_ == nullptr; }
- inline HInstruction* Current() { return instruction_; }
- inline void Advance() {
+ bool Done() const { return instruction_ == nullptr; }
+ HInstruction* Current() const { return instruction_; }
+ void Advance() {
instruction_ = next_;
next_ = Done() ? nullptr : instruction_->next();
}
@@ -236,12 +319,12 @@ class EmbeddedArray {
intptr_t length() const { return N; }
const T& operator[](intptr_t i) const {
- ASSERT(i < length());
+ DCHECK_LT(i, length());
return elements_[i];
}
T& operator[](intptr_t i) {
- ASSERT(i < length());
+ DCHECK_LT(i, length());
return elements_[i];
}
@@ -282,6 +365,11 @@ class HTemplateInstruction: public HInstruction {
virtual intptr_t InputCount() const { return N; }
virtual HInstruction* InputAt(intptr_t i) const { return inputs_[i]; }
+ protected:
+ void SetRawInputAt(intptr_t i, HInstruction* instruction) {
+ inputs_[i] = instruction;
+ }
+
private:
EmbeddedArray<HInstruction*, N> inputs_;
};
@@ -328,10 +416,11 @@ class HGoto : public HTemplateInstruction<0> {
// Conditional branch. A block ending with an HIf instruction must have
// two successors.
-// TODO: Make it take an input.
-class HIf : public HTemplateInstruction<0> {
+class HIf : public HTemplateInstruction<1> {
public:
- HIf() { }
+ explicit HIf(HInstruction* input) {
+ SetRawInputAt(0, input);
+ }
DECLARE_INSTRUCTION(If)
@@ -339,6 +428,76 @@ class HIf : public HTemplateInstruction<0> {
DISALLOW_COPY_AND_ASSIGN(HIf);
};
+// Instruction to check if two inputs are equal to each other.
+class HEqual : public HTemplateInstruction<2> {
+ public:
+ HEqual(HInstruction* first, HInstruction* second) {
+ SetRawInputAt(0, first);
+ SetRawInputAt(1, second);
+ }
+
+ DECLARE_INSTRUCTION(Equal)
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(HEqual);
+};
+
+// A local in the graph. Corresponds to a Dex register.
+class HLocal : public HTemplateInstruction<0> {
+ public:
+ explicit HLocal(uint16_t reg_number) : reg_number_(reg_number) { }
+
+ DECLARE_INSTRUCTION(Local)
+
+ private:
+ // The register number in Dex.
+ uint16_t reg_number_;
+
+ DISALLOW_COPY_AND_ASSIGN(HLocal);
+};
+
+// Load a given local. The local is an input of this instruction.
+class HLoadLocal : public HTemplateInstruction<1> {
+ public:
+ explicit HLoadLocal(HLocal* local) {
+ SetRawInputAt(0, local);
+ }
+
+ DECLARE_INSTRUCTION(LoadLocal)
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(HLoadLocal);
+};
+
+// Store a value in a given local. This instruction has two inputs: the value
+// and the local.
+class HStoreLocal : public HTemplateInstruction<2> {
+ public:
+ HStoreLocal(HLocal* local, HInstruction* value) {
+ SetRawInputAt(0, local);
+ SetRawInputAt(1, value);
+ }
+
+ DECLARE_INSTRUCTION(StoreLocal)
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(HStoreLocal);
+};
+
+// Constants of the type int. Those can be from Dex instructions, or
+// synthesized (for example with the if-eqz instruction).
+class HIntConstant : public HTemplateInstruction<0> {
+ public:
+ explicit HIntConstant(int32_t value) : value_(value) { }
+
+ DECLARE_INSTRUCTION(IntConstant)
+
+ private:
+ const int32_t value_;
+
+ DISALLOW_COPY_AND_ASSIGN(HIntConstant);
+};
+
class HGraphVisitor : public ValueObject {
public:
explicit HGraphVisitor(HGraph* graph) : graph_(graph) { }