summaryrefslogtreecommitdiff
path: root/compiler/optimizing/nodes.h
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing/nodes.h')
-rw-r--r--compiler/optimizing/nodes.h64
1 files changed, 57 insertions, 7 deletions
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 5af3cdd2d6..7d52d7d221 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -521,6 +521,7 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> {
M(ParallelMove, Instruction) \
M(ParameterValue, Instruction) \
M(Phi, Instruction) \
+ M(Rem, BinaryOperation) \
M(Return, Instruction) \
M(ReturnVoid, Instruction) \
M(StaticFieldGet, Instruction) \
@@ -1756,10 +1757,15 @@ class HDiv : public HBinaryOperation {
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.
+ // Special case -1 to avoid getting a SIGFPE on x86(_64).
+ return (y == -1) ? -x : x / y;
+ }
+
+ virtual int64_t Evaluate(int64_t x, int64_t y) const {
+ DCHECK_NE(y, 0);
+ // Special case -1 to avoid getting a SIGFPE on x86(_64).
return (y == -1) ? -x : x / y;
}
- virtual int64_t Evaluate(int64_t x, int64_t y) const { return x / y; }
uint32_t GetDexPc() const { return dex_pc_; }
@@ -1771,6 +1777,33 @@ class HDiv : public HBinaryOperation {
DISALLOW_COPY_AND_ASSIGN(HDiv);
};
+class HRem : public HBinaryOperation {
+ public:
+ HRem(Primitive::Type result_type, HInstruction* left, HInstruction* right, uint32_t dex_pc)
+ : HBinaryOperation(result_type, left, right), dex_pc_(dex_pc) {}
+
+ virtual int32_t Evaluate(int32_t x, int32_t y) const {
+ DCHECK_NE(y, 0);
+ // Special case -1 to avoid getting a SIGFPE on x86(_64).
+ return (y == -1) ? 0 : x % y;
+ }
+
+ virtual int64_t Evaluate(int64_t x, int64_t y) const {
+ DCHECK_NE(y, 0);
+ // Special case -1 to avoid getting a SIGFPE on x86(_64).
+ return (y == -1) ? 0 : x % y;
+ }
+
+ uint32_t GetDexPc() const { return dex_pc_; }
+
+ DECLARE_INSTRUCTION(Rem);
+
+ private:
+ const uint32_t dex_pc_;
+
+ DISALLOW_COPY_AND_ASSIGN(HRem);
+};
+
class HDivZeroCheck : public HExpression<1> {
public:
HDivZeroCheck(HInstruction* value, uint32_t dex_pc)
@@ -2034,6 +2067,8 @@ class HInstanceFieldSet : public HTemplateInstruction<2> {
MemberOffset GetFieldOffset() const { return field_info_.GetFieldOffset(); }
Primitive::Type GetFieldType() const { return field_info_.GetFieldType(); }
+ HInstruction* GetValue() const { return InputAt(1); }
+
DECLARE_INSTRUCTION(InstanceFieldSet);
private:
@@ -2050,13 +2085,16 @@ class HArrayGet : public HExpression<2> {
SetRawInputAt(1, index);
}
- virtual bool CanBeMoved() const { return true; }
- virtual bool InstructionDataEquals(HInstruction* other) const {
+ bool CanBeMoved() const OVERRIDE { return true; }
+ bool InstructionDataEquals(HInstruction* other) const OVERRIDE {
UNUSED(other);
return true;
}
void SetType(Primitive::Type type) { type_ = type; }
+ HInstruction* GetArray() const { return InputAt(0); }
+ HInstruction* GetIndex() const { return InputAt(1); }
+
DECLARE_INSTRUCTION(ArrayGet);
private:
@@ -2072,20 +2110,29 @@ class HArraySet : public HTemplateInstruction<3> {
uint32_t dex_pc)
: HTemplateInstruction(SideEffects::ChangesSomething()),
dex_pc_(dex_pc),
- expected_component_type_(expected_component_type) {
+ expected_component_type_(expected_component_type),
+ needs_type_check_(value->GetType() == Primitive::kPrimNot) {
SetRawInputAt(0, array);
SetRawInputAt(1, index);
SetRawInputAt(2, value);
}
- virtual bool NeedsEnvironment() const {
+ bool NeedsEnvironment() const {
// We currently always call a runtime method to catch array store
// exceptions.
- return InputAt(2)->GetType() == Primitive::kPrimNot;
+ return needs_type_check_;
}
+ void ClearNeedsTypeCheck() {
+ needs_type_check_ = false;
+ }
+
+ bool NeedsTypeCheck() const { return needs_type_check_; }
+
uint32_t GetDexPc() const { return dex_pc_; }
+ HInstruction* GetArray() const { return InputAt(0); }
+ HInstruction* GetIndex() const { return InputAt(1); }
HInstruction* GetValue() const { return InputAt(2); }
Primitive::Type GetComponentType() const {
@@ -2104,6 +2151,7 @@ class HArraySet : public HTemplateInstruction<3> {
private:
const uint32_t dex_pc_;
const Primitive::Type expected_component_type_;
+ bool needs_type_check_;
DISALLOW_COPY_AND_ASSIGN(HArraySet);
};
@@ -2372,6 +2420,8 @@ class HStaticFieldSet : public HTemplateInstruction<2> {
MemberOffset GetFieldOffset() const { return field_info_.GetFieldOffset(); }
Primitive::Type GetFieldType() const { return field_info_.GetFieldType(); }
+ HInstruction* GetValue() const { return InputAt(1); }
+
DECLARE_INSTRUCTION(StaticFieldSet);
private: