Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1244)

Unified Diff: runtime/vm/flow_graph_type_propagator.cc

Issue 12330072: Ensure that compile time types for comparisons are recomputed once comparison are specialized. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/vm/flow_graph_type_propagator.cc
diff --git a/runtime/vm/flow_graph_type_propagator.cc b/runtime/vm/flow_graph_type_propagator.cc
index 75fbb906541bcd1908c628eb544ee4c5cf1a2dd5..8810fbc6c6c00a73bb9e537c84f3579d7174ecc1 100644
--- a/runtime/vm/flow_graph_type_propagator.cc
+++ b/runtime/vm/flow_graph_type_propagator.cc
@@ -106,6 +106,9 @@ void FlowGraphTypePropagator::PropagateRecursive(BlockEntryInstr* block) {
for (intptr_t i = 0; i < instr->InputCount(); i++) {
VisitValue(instr->InputAt(i));
}
+ if (instr->IsDefinition()) {
+ instr->AsDefinition()->RecomputeType();
+ }
instr->Accept(this);
}
@@ -153,7 +156,7 @@ void FlowGraphTypePropagator::SetCid(Definition* def, intptr_t cid) {
CompileType* current = TypeOf(def);
if (current->ToCid() == cid) return;
- SetTypeOf(def, CompileType::FromCid(cid));
+ SetTypeOf(def, ZoneCompileType::Wrap(CompileType::FromCid(cid)));
}
@@ -305,7 +308,7 @@ void CompileType::Union(CompileType* other) {
}
if (IsNone()) {
- ReplaceWith(other);
+ *this = *other;
return;
}
@@ -343,38 +346,38 @@ static bool IsNullableCid(intptr_t cid) {
}
-CompileType* CompileType::New(intptr_t cid, const AbstractType& type) {
- return new CompileType(IsNullableCid(cid), cid, &type);
+CompileType CompileType::Create(intptr_t cid, const AbstractType& type) {
+ return CompileType(IsNullableCid(cid), cid, &type);
}
-CompileType* CompileType::FromAbstractType(const AbstractType& type,
+CompileType CompileType::FromAbstractType(const AbstractType& type,
bool is_nullable) {
- return new CompileType(is_nullable, kIllegalCid, &type);
+ return CompileType(is_nullable, kIllegalCid, &type);
}
-CompileType* CompileType::FromCid(intptr_t cid) {
- return new CompileType(IsNullableCid(cid), cid, NULL);
+CompileType CompileType::FromCid(intptr_t cid) {
+ return CompileType(IsNullableCid(cid), cid, NULL);
}
-CompileType* CompileType::Dynamic() {
- return New(kDynamicCid, Type::ZoneHandle(Type::DynamicType()));
+CompileType CompileType::Dynamic() {
+ return Create(kDynamicCid, Type::ZoneHandle(Type::DynamicType()));
}
-CompileType* CompileType::Null() {
- return New(kNullCid, Type::ZoneHandle(Type::NullType()));
+CompileType CompileType::Null() {
+ return Create(kNullCid, Type::ZoneHandle(Type::NullType()));
}
-CompileType* CompileType::Bool() {
- return New(kBoolCid, Type::ZoneHandle(Type::BoolType()));
+CompileType CompileType::Bool() {
+ return Create(kBoolCid, Type::ZoneHandle(Type::BoolType()));
}
-CompileType* CompileType::Int() {
+CompileType CompileType::Int() {
return FromAbstractType(Type::ZoneHandle(Type::IntType()), kNonNullable);
}
@@ -506,7 +509,16 @@ bool CompileType::CanComputeIsInstanceOf(const AbstractType& type,
bool CompileType::IsMoreSpecificThan(const AbstractType& other) {
- return !IsNone() && ToAbstractType()->IsMoreSpecificThan(other, NULL);
+ if (IsNone()) {
+ return false;
+ }
+
+ if (other.IsVoidType()) {
+ // The only value assignable to void is null.
+ return IsNull();
+ }
+
+ return ToAbstractType()->IsMoreSpecificThan(other, NULL);
}
@@ -518,7 +530,7 @@ CompileType* Value::Type() {
}
-CompileType* PhiInstr::ComputeInitialType() const {
+CompileType PhiInstr::ComputeType() const {
// Initially type of phis is unknown until type propagation is run
// for the first time.
return CompileType::None();
@@ -530,7 +542,7 @@ bool PhiInstr::RecomputeType() {
return false;
}
- CompileType* result = CompileType::None();
+ CompileType result = CompileType::None();
for (intptr_t i = 0; i < InputCount(); i++) {
if (FLAG_trace_type_propagation) {
@@ -540,20 +552,15 @@ bool PhiInstr::RecomputeType() {
InputAt(i)->definition()->ssa_temp_index(),
InputAt(i)->Type()->ToCString());
}
- result->Union(InputAt(i)->Type());
+ result.Union(InputAt(i)->Type());
}
- if (result->IsNone()) {
+ if (result.IsNone()) {
ASSERT(Type()->IsNone());
return false;
}
- if (Type()->IsNone() || !Type()->IsEqualTo(result)) {
- Type()->ReplaceWith(result);
- return true;
- }
-
- return false;
+ return UpdateType(result);
}
@@ -568,7 +575,7 @@ static bool CanTrustParameterType(const Function& function, intptr_t index) {
}
-CompileType* ParameterInstr::ComputeInitialType() const {
+CompileType ParameterInstr::ComputeType() const {
// Note that returning the declared type of the formal parameter would be
// incorrect, because ParameterInstr is used as input to the type check
// verifying the run time type of the passed-in parameter and this check would
@@ -586,18 +593,18 @@ CompileType* ParameterInstr::ComputeInitialType() const {
}
-CompileType* PushArgumentInstr::ComputeInitialType() const {
+CompileType PushArgumentInstr::ComputeType() const {
return CompileType::Dynamic();
}
-CompileType* ConstantInstr::ComputeInitialType() const {
+CompileType ConstantInstr::ComputeType() const {
if (value().IsNull()) {
return CompileType::Null();
}
if (value().IsInstance()) {
- return CompileType::New(
+ return CompileType::Create(
Class::Handle(value().clazz()).id(),
AbstractType::ZoneHandle(Instance::Cast(value()).GetType()));
} else {
@@ -609,10 +616,17 @@ CompileType* ConstantInstr::ComputeInitialType() const {
CompileType* AssertAssignableInstr::ComputeInitialType() const {
CompileType* value_type = value()->Type();
+
if (value_type->IsMoreSpecificThan(dst_type())) {
return value_type;
}
- return CompileType::FromAbstractType(dst_type());
+
+ if (dst_type().IsVoidType()) {
+ // The only value assignable to void is null.
+ return ZoneCompileType::Wrap(CompileType::Null());
+ }
+
+ return ZoneCompileType::Wrap(CompileType::FromAbstractType(dst_type()));
}
@@ -622,69 +636,77 @@ bool AssertAssignableInstr::RecomputeType() {
return false;
}
- if (value_type->IsMoreSpecificThan(dst_type()) &&
- !Type()->IsEqualTo(value_type)) {
- Type()->ReplaceWith(value_type);
- return true;
+ if (value_type->IsMoreSpecificThan(dst_type())) {
+ return UpdateType(*value_type);
}
return false;
}
-CompileType* AssertBooleanInstr::ComputeInitialType() const {
+CompileType AssertBooleanInstr::ComputeType() const {
return CompileType::Bool();
}
-CompileType* ArgumentDefinitionTestInstr::ComputeInitialType() const {
+CompileType ArgumentDefinitionTestInstr::ComputeType() const {
return CompileType::Bool();
}
-CompileType* BooleanNegateInstr::ComputeInitialType() const {
+CompileType BooleanNegateInstr::ComputeType() const {
return CompileType::Bool();
}
-CompileType* InstanceOfInstr::ComputeInitialType() const {
+CompileType InstanceOfInstr::ComputeType() const {
return CompileType::Bool();
}
-CompileType* StrictCompareInstr::ComputeInitialType() const {
+CompileType StrictCompareInstr::ComputeType() const {
return CompileType::Bool();
}
-CompileType* EqualityCompareInstr::ComputeInitialType() const {
+CompileType EqualityCompareInstr::ComputeType() const {
return IsInlinedNumericComparison() ? CompileType::Bool()
: CompileType::Dynamic();
}
-CompileType* RelationalOpInstr::ComputeInitialType() const {
+bool EqualityCompareInstr::RecomputeType() {
+ return UpdateType(ComputeType());
+}
+
+
+CompileType RelationalOpInstr::ComputeType() const {
return IsInlinedNumericComparison() ? CompileType::Bool()
: CompileType::Dynamic();
}
-CompileType* CurrentContextInstr::ComputeInitialType() const {
+bool RelationalOpInstr::RecomputeType() {
+ return UpdateType(ComputeType());
+}
+
+
+CompileType CurrentContextInstr::ComputeType() const {
return CompileType::FromCid(kContextCid);
}
-CompileType* CloneContextInstr::ComputeInitialType() const {
+CompileType CloneContextInstr::ComputeType() const {
return CompileType::FromCid(kContextCid);
}
-CompileType* AllocateContextInstr::ComputeInitialType() const {
+CompileType AllocateContextInstr::ComputeType() const {
return CompileType::FromCid(kContextCid);
}
-CompileType* StaticCallInstr::ComputeInitialType() const {
+CompileType StaticCallInstr::ComputeType() const {
if (result_cid_ != kDynamicCid) {
return CompileType::FromCid(result_cid_);
}
@@ -698,7 +720,7 @@ CompileType* StaticCallInstr::ComputeInitialType() const {
}
-CompileType* LoadLocalInstr::ComputeInitialType() const {
+CompileType LoadLocalInstr::ComputeType() const {
if (FLAG_enable_type_checks) {
return CompileType::FromAbstractType(local().type());
}
@@ -712,7 +734,7 @@ CompileType* StoreLocalInstr::ComputeInitialType() const {
}
-CompileType* StringFromCharCodeInstr::ComputeInitialType() const {
+CompileType StringFromCharCodeInstr::ComputeType() const {
return CompileType::FromCid(cid_);
}
@@ -722,7 +744,7 @@ CompileType* StoreInstanceFieldInstr::ComputeInitialType() const {
}
-CompileType* LoadStaticFieldInstr::ComputeInitialType() const {
+CompileType LoadStaticFieldInstr::ComputeType() const {
if (FLAG_enable_type_checks) {
return CompileType::FromAbstractType(
AbstractType::ZoneHandle(field().type()));
@@ -736,12 +758,12 @@ CompileType* StoreStaticFieldInstr::ComputeInitialType() const {
}
-CompileType* CreateArrayInstr::ComputeInitialType() const {
+CompileType CreateArrayInstr::ComputeType() const {
return CompileType::FromAbstractType(type(), CompileType::kNonNullable);
}
-CompileType* CreateClosureInstr::ComputeInitialType() const {
+CompileType CreateClosureInstr::ComputeType() const {
const Function& fun = function();
const Class& signature_class = Class::Handle(fun.signature_class());
return CompileType::FromAbstractType(
@@ -750,13 +772,13 @@ CompileType* CreateClosureInstr::ComputeInitialType() const {
}
-CompileType* AllocateObjectInstr::ComputeInitialType() const {
+CompileType AllocateObjectInstr::ComputeType() const {
// TODO(vegorov): Incorporate type arguments into the returned type.
return CompileType::FromCid(cid_);
}
-CompileType* LoadFieldInstr::ComputeInitialType() const {
+CompileType LoadFieldInstr::ComputeType() const {
// Type may be null if the field is a VM field, e.g. context parent.
// Keep it as null for debug purposes and do not return dynamic in production
// mode, since misuse of the type would remain undetected.
@@ -777,87 +799,87 @@ CompileType* StoreVMFieldInstr::ComputeInitialType() const {
}
-CompileType* BinarySmiOpInstr::ComputeInitialType() const {
+CompileType BinarySmiOpInstr::ComputeType() const {
return CompileType::FromCid(kSmiCid);
}
-CompileType* UnarySmiOpInstr::ComputeInitialType() const {
+CompileType UnarySmiOpInstr::ComputeType() const {
return CompileType::FromCid(kSmiCid);
}
-CompileType* DoubleToSmiInstr::ComputeInitialType() const {
+CompileType DoubleToSmiInstr::ComputeType() const {
return CompileType::FromCid(kSmiCid);
}
-CompileType* ConstraintInstr::ComputeInitialType() const {
+CompileType ConstraintInstr::ComputeType() const {
return CompileType::FromCid(kSmiCid);
}
-CompileType* BinaryMintOpInstr::ComputeInitialType() const {
+CompileType BinaryMintOpInstr::ComputeType() const {
return CompileType::Int();
}
-CompileType* ShiftMintOpInstr::ComputeInitialType() const {
+CompileType ShiftMintOpInstr::ComputeType() const {
return CompileType::Int();
}
-CompileType* UnaryMintOpInstr::ComputeInitialType() const {
+CompileType UnaryMintOpInstr::ComputeType() const {
return CompileType::Int();
}
-CompileType* BoxIntegerInstr::ComputeInitialType() const {
+CompileType BoxIntegerInstr::ComputeType() const {
return CompileType::Int();
}
-CompileType* UnboxIntegerInstr::ComputeInitialType() const {
+CompileType UnboxIntegerInstr::ComputeType() const {
return CompileType::Int();
}
-CompileType* DoubleToIntegerInstr::ComputeInitialType() const {
+CompileType DoubleToIntegerInstr::ComputeType() const {
return CompileType::Int();
}
-CompileType* BinaryDoubleOpInstr::ComputeInitialType() const {
+CompileType BinaryDoubleOpInstr::ComputeType() const {
return CompileType::FromCid(kDoubleCid);
}
-CompileType* MathSqrtInstr::ComputeInitialType() const {
+CompileType MathSqrtInstr::ComputeType() const {
return CompileType::FromCid(kDoubleCid);
}
-CompileType* UnboxDoubleInstr::ComputeInitialType() const {
+CompileType UnboxDoubleInstr::ComputeType() const {
return CompileType::FromCid(kDoubleCid);
}
-CompileType* BoxDoubleInstr::ComputeInitialType() const {
+CompileType BoxDoubleInstr::ComputeType() const {
return CompileType::FromCid(kDoubleCid);
}
-CompileType* SmiToDoubleInstr::ComputeInitialType() const {
+CompileType SmiToDoubleInstr::ComputeType() const {
return CompileType::FromCid(kDoubleCid);
}
-CompileType* DoubleToDoubleInstr::ComputeInitialType() const {
+CompileType DoubleToDoubleInstr::ComputeType() const {
return CompileType::FromCid(kDoubleCid);
}
-CompileType* InvokeMathCFunctionInstr::ComputeInitialType() const {
+CompileType InvokeMathCFunctionInstr::ComputeType() const {
return CompileType::FromCid(kDoubleCid);
}

Powered by Google App Engine
This is Rietveld 408576698