diff options
Diffstat (limited to 'compiler/optimizing/nodes.h')
| -rw-r--r-- | compiler/optimizing/nodes.h | 105 |
1 files changed, 100 insertions, 5 deletions
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 79638b3545..37e5e6b9aa 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -292,7 +292,8 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> { block_id_(-1), dex_pc_(dex_pc), lifetime_start_(kNoLifetime), - lifetime_end_(kNoLifetime) {} + lifetime_end_(kNoLifetime), + is_catch_block_(false) {} const GrowableArray<HBasicBlock*>& GetPredecessors() const { return predecessors_; @@ -450,6 +451,9 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> { uint32_t GetDexPc() const { return dex_pc_; } + bool IsCatchBlock() const { return is_catch_block_; } + void SetIsCatchBlock() { is_catch_block_ = true; } + private: HGraph* const graph_; GrowableArray<HBasicBlock*> predecessors_; @@ -464,6 +468,7 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> { const uint32_t dex_pc_; size_t lifetime_start_; size_t lifetime_end_; + bool is_catch_block_; DISALLOW_COPY_AND_ASSIGN(HBasicBlock); }; @@ -478,6 +483,7 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> { M(Compare, BinaryOperation) \ M(Condition, BinaryOperation) \ M(Div, BinaryOperation) \ + M(DivZeroCheck, Instruction) \ M(DoubleConstant, Constant) \ M(Equal, Condition) \ M(Exit, Instruction) \ @@ -494,6 +500,7 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> { M(LessThan, Condition) \ M(LessThanOrEqual, Condition) \ M(LoadClass, Instruction) \ + M(LoadException, Instruction) \ M(LoadLocal, Instruction) \ M(LoadString, Instruction) \ M(Local, Instruction) \ @@ -516,6 +523,8 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> { M(Sub, BinaryOperation) \ M(SuspendCheck, Instruction) \ M(Temporary, Instruction) \ + M(Throw, Instruction) \ + M(TypeConversion, Instruction) \ #define FOR_EACH_INSTRUCTION(M) \ FOR_EACH_CONCRETE_INSTRUCTION(M) \ @@ -1050,7 +1059,7 @@ class HReturn : public HTemplateInstruction<1> { }; // The exit instruction is the only instruction of the exit block. -// Instructions aborting the method (HTrow and HReturn) must branch to the +// Instructions aborting the method (HThrow and HReturn) must branch to the // exit block. class HExit : public HTemplateInstruction<0> { public: @@ -1069,7 +1078,7 @@ class HGoto : public HTemplateInstruction<0> { public: HGoto() : HTemplateInstruction(SideEffects::None()) {} - virtual bool IsControlFlow() const { return true; } + bool IsControlFlow() const OVERRIDE { return true; } HBasicBlock* GetSuccessor() const { return GetBlock()->GetSuccessors().Get(0); @@ -1090,7 +1099,7 @@ class HIf : public HTemplateInstruction<1> { SetRawInputAt(0, input); } - virtual bool IsControlFlow() const { return true; } + bool IsControlFlow() const OVERRIDE { return true; } HBasicBlock* IfTrueSuccessor() const { return GetBlock()->GetSuccessors().Get(0); @@ -1713,7 +1722,12 @@ class HDiv : public HBinaryOperation { HDiv(Primitive::Type result_type, HInstruction* left, HInstruction* right) : HBinaryOperation(result_type, left, right) {} - virtual int32_t Evaluate(int32_t x, int32_t y) const { return x / y; } + virtual int32_t Evaluate(int32_t x, int32_t y) const { + // Our graph structure ensures we never have 0 for `y` during constant folding. + DCHECK_NE(y, 0); + // Special case -1 to avoid getting a SIGFPE on x86. + return (y == -1) ? -x : x / y; + } virtual int64_t Evaluate(int64_t x, int64_t y) const { return x / y; } DECLARE_INSTRUCTION(Div); @@ -1722,6 +1736,33 @@ class HDiv : public HBinaryOperation { DISALLOW_COPY_AND_ASSIGN(HDiv); }; +class HDivZeroCheck : public HExpression<1> { + public: + HDivZeroCheck(HInstruction* value, uint32_t dex_pc) + : HExpression(value->GetType(), SideEffects::None()), dex_pc_(dex_pc) { + SetRawInputAt(0, value); + } + + bool CanBeMoved() const OVERRIDE { return true; } + + bool InstructionDataEquals(HInstruction* other) const OVERRIDE { + UNUSED(other); + return true; + } + + bool NeedsEnvironment() const OVERRIDE { return true; } + bool CanThrow() const OVERRIDE { return true; } + + uint32_t GetDexPc() const { return dex_pc_; } + + DECLARE_INSTRUCTION(DivZeroCheck); + + private: + const uint32_t dex_pc_; + + DISALLOW_COPY_AND_ASSIGN(HDivZeroCheck); +}; + // The value of a parameter in this method. Its location depends on // the calling convention. class HParameterValue : public HExpression<0> { @@ -1761,6 +1802,28 @@ class HNot : public HUnaryOperation { DISALLOW_COPY_AND_ASSIGN(HNot); }; +class HTypeConversion : public HExpression<1> { + public: + // Instantiate a type conversion of `input` to `result_type`. + HTypeConversion(Primitive::Type result_type, HInstruction* input) + : HExpression(result_type, SideEffects::None()) { + SetRawInputAt(0, input); + DCHECK_NE(input->GetType(), result_type); + } + + HInstruction* GetInput() const { return InputAt(0); } + Primitive::Type GetInputType() const { return GetInput()->GetType(); } + Primitive::Type GetResultType() const { return GetType(); } + + bool CanBeMoved() const OVERRIDE { return true; } + bool InstructionDataEquals(HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE { return true; } + + DECLARE_INSTRUCTION(TypeConversion); + + private: + DISALLOW_COPY_AND_ASSIGN(HTypeConversion); +}; + class HPhi : public HInstruction { public: HPhi(ArenaAllocator* arena, uint32_t reg_number, size_t number_of_inputs, Primitive::Type type) @@ -2228,6 +2291,38 @@ class HStaticFieldSet : public HTemplateInstruction<2> { DISALLOW_COPY_AND_ASSIGN(HStaticFieldSet); }; +// Implement the move-exception DEX instruction. +class HLoadException : public HExpression<0> { + public: + HLoadException() : HExpression(Primitive::kPrimNot, SideEffects::None()) {} + + DECLARE_INSTRUCTION(LoadException); + + private: + DISALLOW_COPY_AND_ASSIGN(HLoadException); +}; + +class HThrow : public HTemplateInstruction<1> { + public: + HThrow(HInstruction* exception, uint32_t dex_pc) + : HTemplateInstruction(SideEffects::None()), dex_pc_(dex_pc) { + SetRawInputAt(0, exception); + } + + bool IsControlFlow() const OVERRIDE { return true; } + + bool NeedsEnvironment() const OVERRIDE { return true; } + + uint32_t GetDexPc() const { return dex_pc_; } + + DECLARE_INSTRUCTION(Throw); + + private: + uint32_t dex_pc_; + + DISALLOW_COPY_AND_ASSIGN(HThrow); +}; + class MoveOperands : public ArenaObject<kArenaAllocMisc> { public: MoveOperands(Location source, Location destination, HInstruction* instruction) |