diff options
Diffstat (limited to 'compiler/optimizing/nodes.h')
-rw-r--r-- | compiler/optimizing/nodes.h | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 0f2c1cffee..19957971c2 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -4238,7 +4238,7 @@ class HPhi : public HInstruction { inputs_(number_of_inputs, arena->Adapter(kArenaAllocPhiInputs)), reg_number_(reg_number), type_(type), - is_live_(false), + is_live_(true), can_be_null_(true) { } @@ -4263,7 +4263,18 @@ class HPhi : public HInstruction { void RemoveInputAt(size_t index); Primitive::Type GetType() const OVERRIDE { return type_; } - void SetType(Primitive::Type type) { type_ = type; } + void SetType(Primitive::Type new_type) { + // Make sure that only valid type changes occur. The following are allowed: + // (1) void -> * (initial type assignment), + // (2) int -> float/ref (primitive type propagation), + // (3) long -> double (primitive type propagation). + DCHECK(type_ == new_type || + type_ == Primitive::kPrimVoid || + (type_ == Primitive::kPrimInt && new_type == Primitive::kPrimFloat) || + (type_ == Primitive::kPrimInt && new_type == Primitive::kPrimNot) || + (type_ == Primitive::kPrimLong && new_type == Primitive::kPrimDouble)); + type_ = new_type; + } bool CanBeNull() const OVERRIDE { return can_be_null_; } void SetCanBeNull(bool can_be_null) { can_be_null_ = can_be_null; } @@ -4485,7 +4496,8 @@ class HArrayGet : public HExpression<2> { SideEffects additional_side_effects = SideEffects::None()) : HExpression(type, SideEffects::ArrayReadOfType(type).Union(additional_side_effects), - dex_pc) { + dex_pc), + fixed_type_(type != Primitive::kPrimInt && type != Primitive::kPrimLong) { SetRawInputAt(0, array); SetRawInputAt(1, index); } @@ -4503,7 +4515,13 @@ class HArrayGet : public HExpression<2> { return false; } - void SetType(Primitive::Type type) { type_ = type; } + void SetType(Primitive::Type type) { + DCHECK(type_ == type || !IsTypeFixed()); + type_ = type; + } + + bool IsTypeFixed() const { return fixed_type_; } + void FixType() { fixed_type_ = true; } HInstruction* GetArray() const { return InputAt(0); } HInstruction* GetIndex() const { return InputAt(1); } @@ -4511,6 +4529,12 @@ class HArrayGet : public HExpression<2> { DECLARE_INSTRUCTION(ArrayGet); private: + // Bytecode aget(-wide) instructions have ambiguous type (int/float, long/double). + // If the type can be determined from uses, `fixed_type_` should be set to true, + // to prevent PrimitiveTypePropagation from changing it while typing phis. With + // other aget-* variants, the type is always unambiguous. + bool fixed_type_; + DISALLOW_COPY_AND_ASSIGN(HArrayGet); }; |