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.h32
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);
};