diff options
Diffstat (limited to 'compiler/optimizing/nodes.h')
| -rw-r--r-- | compiler/optimizing/nodes.h | 107 |
1 files changed, 98 insertions, 9 deletions
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index e87b044cc9..bb699e47c3 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -408,7 +408,7 @@ class HBasicBlock : public ArenaObject { DISALLOW_COPY_AND_ASSIGN(HBasicBlock); }; -#define FOR_EACH_INSTRUCTION(M) \ +#define FOR_EACH_CONCRETE_INSTRUCTION(M) \ M(Add) \ M(Condition) \ M(Equal) \ @@ -437,9 +437,16 @@ class HBasicBlock : public ArenaObject { M(Compare) \ M(InstanceFieldGet) \ M(InstanceFieldSet) \ + M(ArrayGet) \ + M(ArraySet) \ + M(ArrayLength) \ + M(BoundsCheck) \ M(NullCheck) \ M(Temporary) \ +#define FOR_EACH_INSTRUCTION(M) \ + FOR_EACH_CONCRETE_INSTRUCTION(M) \ + M(Constant) #define FORWARD_DECLARATION(type) class H##type; FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) @@ -494,6 +501,7 @@ class HInstruction : public ArenaObject { void SetBlock(HBasicBlock* block) { block_ = block; } bool IsInBlock() const { return block_ != nullptr; } bool IsInLoop() const { return block_->IsInLoop(); } + bool IsLoopHeaderPhi() { return IsPhi() && block_->IsLoopHeader(); } virtual size_t InputCount() const = 0; virtual HInstruction* InputAt(size_t i) const = 0; @@ -1078,11 +1086,21 @@ class HStoreLocal : public HTemplateInstruction<2> { DISALLOW_COPY_AND_ASSIGN(HStoreLocal); }; +class HConstant : public HExpression<0> { + public: + explicit HConstant(Primitive::Type type) : HExpression(type) {} + + DECLARE_INSTRUCTION(Constant); + + private: + DISALLOW_COPY_AND_ASSIGN(HConstant); +}; + // Constants of the type int. Those can be from Dex instructions, or // synthesized (for example with the if-eqz instruction). -class HIntConstant : public HExpression<0> { +class HIntConstant : public HConstant { public: - explicit HIntConstant(int32_t value) : HExpression(Primitive::kPrimInt), value_(value) {} + explicit HIntConstant(int32_t value) : HConstant(Primitive::kPrimInt), value_(value) {} int32_t GetValue() const { return value_; } @@ -1094,14 +1112,12 @@ class HIntConstant : public HExpression<0> { DISALLOW_COPY_AND_ASSIGN(HIntConstant); }; -class HLongConstant : public HExpression<0> { +class HLongConstant : public HConstant { public: - explicit HLongConstant(int64_t value) : HExpression(Primitive::kPrimLong), value_(value) {} + explicit HLongConstant(int64_t value) : HConstant(Primitive::kPrimLong), value_(value) {} int64_t GetValue() const { return value_; } - virtual Primitive::Type GetType() const { return Primitive::kPrimLong; } - DECLARE_INSTRUCTION(LongConstant); private: @@ -1278,13 +1294,12 @@ class HPhi : public HInstruction { DECLARE_INSTRUCTION(Phi); - protected: + private: GrowableArray<HInstruction*> inputs_; const uint32_t reg_number_; Primitive::Type type_; bool is_live_; - private: DISALLOW_COPY_AND_ASSIGN(HPhi); }; @@ -1357,6 +1372,80 @@ class HInstanceFieldSet : public HTemplateInstruction<2> { DISALLOW_COPY_AND_ASSIGN(HInstanceFieldSet); }; +class HArrayGet : public HExpression<2> { + public: + HArrayGet(HInstruction* array, HInstruction* index, Primitive::Type type) + : HExpression(type) { + SetRawInputAt(0, array); + SetRawInputAt(1, index); + } + + DECLARE_INSTRUCTION(ArrayGet); + + private: + DISALLOW_COPY_AND_ASSIGN(HArrayGet); +}; + +class HArraySet : public HTemplateInstruction<3> { + public: + HArraySet(HInstruction* array, + HInstruction* index, + HInstruction* value, + uint32_t dex_pc) : dex_pc_(dex_pc) { + SetRawInputAt(0, array); + SetRawInputAt(1, index); + SetRawInputAt(2, value); + } + + virtual bool NeedsEnvironment() const { + // We currently always call a runtime method to catch array store + // exceptions. + return InputAt(2)->GetType() == Primitive::kPrimNot; + } + + uint32_t GetDexPc() const { return dex_pc_; } + + DECLARE_INSTRUCTION(ArraySet); + + private: + const uint32_t dex_pc_; + + DISALLOW_COPY_AND_ASSIGN(HArraySet); +}; + +class HArrayLength : public HExpression<1> { + public: + explicit HArrayLength(HInstruction* array) : HExpression(Primitive::kPrimInt) { + SetRawInputAt(0, array); + } + + DECLARE_INSTRUCTION(ArrayLength); + + private: + DISALLOW_COPY_AND_ASSIGN(HArrayLength); +}; + +class HBoundsCheck : public HExpression<2> { + public: + HBoundsCheck(HInstruction* index, HInstruction* length, uint32_t dex_pc) + : HExpression(index->GetType()), dex_pc_(dex_pc) { + DCHECK(index->GetType() == Primitive::kPrimInt); + SetRawInputAt(0, index); + SetRawInputAt(1, length); + } + + virtual bool NeedsEnvironment() const { return true; } + + uint32_t GetDexPc() const { return dex_pc_; } + + DECLARE_INSTRUCTION(BoundsCheck); + + private: + const uint32_t dex_pc_; + + DISALLOW_COPY_AND_ASSIGN(HBoundsCheck); +}; + /** * Some DEX instructions are folded into multiple HInstructions that need * to stay live until the last HInstruction. This class |