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

Unified Diff: runtime/vm/intermediate_language.cc

Issue 10831252: Revert r10475. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 4 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
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/object.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/intermediate_language.cc
===================================================================
--- runtime/vm/intermediate_language.cc (revision 10475)
+++ runtime/vm/intermediate_language.cc (working copy)
@@ -117,10 +117,10 @@
}
-// Returns true if the compile type of this value is more specific than the
+// Returns true if the static type of this value is more specific than the
// given dst_type.
-// TODO(regis): Support a set of compile types for the given value.
-bool Value::CompileTypeIsMoreSpecificThan(const AbstractType& dst_type) const {
+// TODO(regis): Should we support a set of static types?
+bool Value::StaticTypeIsMoreSpecificThan(const AbstractType& dst_type) const {
ASSERT(!dst_type.IsMalformed()); // Should be tested by caller.
ASSERT(!dst_type.IsDynamicType()); // Should be tested by caller.
ASSERT(!dst_type.IsObjectType()); // Should be tested by caller.
@@ -141,18 +141,18 @@
return false;
}
- // Consider the compile type of the value.
- const AbstractType& compile_type = AbstractType::Handle(CompileType());
- ASSERT(!compile_type.IsMalformed());
+ // Consider the static type of the value.
+ const AbstractType& static_type = AbstractType::Handle(StaticType());
+ ASSERT(!static_type.IsMalformed());
- // If the compile type of the value is void, we are type checking the result
- // of a void function, which was checked to be null at the return statement
+ // If the static type of the value is void, we are type checking the result of
+ // a void function, which was checked to be null at the return statement
// inside the function.
- if (compile_type.IsVoidType()) {
+ if (static_type.IsVoidType()) {
return true;
}
- // If the compile type of the value is NullType, the type test is eliminated.
+ // If the static type of the value is NullType, the type test is eliminated.
// There are only three instances that can be of Class Null:
// Object::null(), Object::sentinel(), and Object::transition_sentinel().
// The inline code and run time code performing the type check will never
@@ -160,53 +160,40 @@
// will always be eliminated here, because these sentinel values can only
// be encountered as constants, never as actual value of a heap object
// being type checked.
- if (compile_type.IsNullType()) {
+ if (static_type.IsNullType()) {
return true;
}
// The run time type of the value is guaranteed to be a subtype of the
- // compile time type of the value. However, establishing here that
- // the compile time type is a subtype of the destination type does not
- // guarantee that the run time type will also be a subtype of the destination
- // type, because the subtype relation is not transitive.
+ // compile time static type of the value. However, establishing here that
+ // the static type is a subtype of the destination type does not guarantee
+ // that the run time type will also be a subtype of the destination type,
+ // because the subtype relation is not transitive.
// However, the 'more specific than' relation is transitive and is used
- // here. In other words, if the compile type of the value is more specific
+ // here. In other words, if the static type of the value is more specific
// than the destination type, the run time type of the value, which is
- // guaranteed to be a subtype of the compile type, is also guaranteed to be
+ // guaranteed to be a subtype of the static type, is also guaranteed to be
// a subtype of the destination type and the type check can therefore be
// eliminated.
- return compile_type.IsMoreSpecificThan(dst_type, NULL);
+ return static_type.IsMoreSpecificThan(dst_type, NULL);
}
-RawAbstractType* PhiInstr::CompileType() const {
- if (HasPropagatedType()) {
- return PropagatedType();
- }
- // If type propagation has not yet occured, we are reaching this phi via a
- // back edge phi input. Return null as compile type so that this input is
- // ignored in the first iteration of type propagation.
- return AbstractType::null();
-}
-
-
-RawAbstractType* PhiInstr::LeastSpecificInputType() const {
- AbstractType& least_specific_type = AbstractType::Handle();
+RawAbstractType* PhiInstr::StaticType() const {
+ // TODO(regis): Return the least upper bound of the input static types.
+ // It is much simpler to compute the least specific of the input static types,
+ // and it may be good enough in practice.
+ // Even better: we could keep the set of the input static types intact.
+ AbstractType& least_specific_type =
+ AbstractType::Handle(InputAt(0)->StaticType());
AbstractType& input_type = AbstractType::Handle();
- for (intptr_t i = 0; i < InputCount(); i++) {
- input_type = InputAt(i)->CompileType();
- if (input_type.IsNull()) {
- // This input is on a back edge and we are in the first iteration of type
- // propagation. Ignore it.
- continue;
- }
- ASSERT(!input_type.IsNull());
- if (least_specific_type.IsNull() ||
- least_specific_type.IsMoreSpecificThan(input_type, NULL)) {
+ for (intptr_t i = 1; i < InputCount(); i++) {
+ input_type = InputAt(i)->StaticType();
+ if (input_type.IsMoreSpecificThan(least_specific_type, NULL)) {
+ // Type least_specific_type is less specific than input_type. No change.
+ } else if (least_specific_type.IsMoreSpecificThan(input_type, NULL)) {
// Type input_type is less specific than the current least_specific_type.
least_specific_type = input_type.raw();
- } else if (input_type.IsMoreSpecificThan(least_specific_type, NULL)) {
- // Type least_specific_type is less specific than input_type. No change.
} else {
// The types are unrelated. No need to continue.
least_specific_type = Type::ObjectType();
@@ -217,17 +204,13 @@
}
-RawAbstractType* ParameterInstr::CompileType() const {
- // TODO(regis): Can type feedback provide information about the compile type
- // of a passed-in parameter? In that case, it would be stored in the
- // propagated_type_ field.
- if (HasPropagatedType()) {
- return PropagatedType();
- }
- // 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
- // always be wrongly eliminated.
+RawAbstractType* ParameterInstr::StaticType() const {
+ // TODO(regis): Can type feedback provide information about the static type
+ // of a passed-in parameter?
+ // Note that in checked mode, we could return the static type of the formal
+ // parameter. However, this would be wrong if ParameterInstr is used to type
+ // check the passed-in parameter, since the type check would then always be
+ // wrongly eliminated.
return Type::DynamicType();
}
@@ -261,16 +244,6 @@
}
-RawAbstractType* BindInstr::CompileType() const {
- if (HasPropagatedType()) {
- return PropagatedType();
- }
- // The compile type may be requested when building the flow graph, i.e. before
- // type propagation has occurred.
- return computation()->CompileType();
-}
-
-
void BindInstr::RecordAssignedVars(BitVector* assigned_vars,
intptr_t fixed_parameter_count) {
computation()->RecordAssignedVars(assigned_vars, fixed_parameter_count);
@@ -497,76 +470,77 @@
}
-RawAbstractType* ConstantVal::CompileType() const {
- if (value().IsNull()) {
- return Type::NullType();
- }
+// ==== Support for propagating static type.
+RawAbstractType* ConstantVal::StaticType() const {
if (value().IsInstance()) {
return Instance::Cast(value()).GetType();
} else {
- ASSERT(value().IsAbstractTypeArguments());
+ UNREACHABLE();
return AbstractType::null();
}
}
-RawAbstractType* UseVal::CompileType() const {
- return definition()->CompileType();
+RawAbstractType* UseVal::StaticType() const {
+ return definition()->StaticType();
}
-RawAbstractType* AssertAssignableComp::CompileType() const {
- const AbstractType& value_compile_type =
- AbstractType::Handle(value()->CompileType());
- if (value_compile_type.IsMoreSpecificThan(dst_type(), NULL)) {
- return value_compile_type.raw();
+RawAbstractType* AssertAssignableComp::StaticType() const {
+ const AbstractType& value_static_type =
+ AbstractType::Handle(value()->StaticType());
+ if (value_static_type.IsMoreSpecificThan(dst_type(), NULL)) {
+ return value_static_type.raw();
}
return dst_type().raw();
}
-RawAbstractType* AssertBooleanComp::CompileType() const {
+RawAbstractType* AssertBooleanComp::StaticType() const {
return Type::BoolInterface();
}
-RawAbstractType* CurrentContextComp::CompileType() const {
+RawAbstractType* CurrentContextComp::StaticType() const {
+ UNREACHABLE();
return AbstractType::null();
}
-RawAbstractType* StoreContextComp::CompileType() const {
+RawAbstractType* StoreContextComp::StaticType() const {
+ UNREACHABLE();
return AbstractType::null();
}
-RawAbstractType* ClosureCallComp::CompileType() const {
- // Because of function subtyping rules, the declared return type of a closure
- // call cannot be relied upon for compile type analysis. For example, a
+RawAbstractType* ClosureCallComp::StaticType() const {
+ // Because of function subtyping rules, the static return type of a closure
+ // call cannot be relied upon for static type analysis. For example, a
// function returning Dynamic can be assigned to a closure variable declared
// to return int and may actually return a double at run-time.
return Type::DynamicType();
}
-RawAbstractType* InstanceCallComp::CompileType() const {
+RawAbstractType* InstanceCallComp::StaticType() const {
// TODO(regis): Return a more specific type than Dynamic for recognized
- // combinations of receiver type and method name.
+ // combinations of receiver static type and method name.
return Type::DynamicType();
}
-RawAbstractType* PolymorphicInstanceCallComp::CompileType() const {
+RawAbstractType* PolymorphicInstanceCallComp::StaticType() const {
return Type::DynamicType();
}
-RawAbstractType* StaticCallComp::CompileType() const {
+RawAbstractType* StaticCallComp::StaticType() const {
return function().result_type();
}
-RawAbstractType* LoadLocalComp::CompileType() const {
+RawAbstractType* LoadLocalComp::StaticType() const {
+ // TODO(regis): Verify that the type of the receiver is properly set.
if (FLAG_enable_type_checks) {
return local().type().raw();
}
@@ -574,27 +548,27 @@
}
-RawAbstractType* StoreLocalComp::CompileType() const {
- return value()->CompileType();
+RawAbstractType* StoreLocalComp::StaticType() const {
+ return value()->StaticType();
}
-RawAbstractType* StrictCompareComp::CompileType() const {
+RawAbstractType* StrictCompareComp::StaticType() const {
return Type::BoolInterface();
}
-RawAbstractType* EqualityCompareComp::CompileType() const {
+RawAbstractType* EqualityCompareComp::StaticType() const {
return Type::BoolInterface();
}
-RawAbstractType* RelationalOpComp::CompileType() const {
+RawAbstractType* RelationalOpComp::StaticType() const {
return Type::BoolInterface();
}
-RawAbstractType* NativeCallComp::CompileType() const {
+RawAbstractType* NativeCallComp::StaticType() const {
// The result type of the native function is identical to the result type of
// the enclosing native Dart function. However, we prefer to check the type
// of the value returned from the native call.
@@ -602,17 +576,18 @@
}
-RawAbstractType* LoadIndexedComp::CompileType() const {
+RawAbstractType* LoadIndexedComp::StaticType() const {
return Type::DynamicType();
}
-RawAbstractType* StoreIndexedComp::CompileType() const {
+RawAbstractType* StoreIndexedComp::StaticType() const {
+ UNREACHABLE();
return AbstractType::null();
}
-RawAbstractType* LoadInstanceFieldComp::CompileType() const {
+RawAbstractType* LoadInstanceFieldComp::StaticType() const {
if (FLAG_enable_type_checks) {
return field().type();
}
@@ -620,12 +595,12 @@
}
-RawAbstractType* StoreInstanceFieldComp::CompileType() const {
- return value()->CompileType();
+RawAbstractType* StoreInstanceFieldComp::StaticType() const {
+ return value()->StaticType();
}
-RawAbstractType* LoadStaticFieldComp::CompileType() const {
+RawAbstractType* LoadStaticFieldComp::StaticType() const {
if (FLAG_enable_type_checks) {
return field().type();
}
@@ -633,119 +608,127 @@
}
-RawAbstractType* StoreStaticFieldComp::CompileType() const {
- return value()->CompileType();
+RawAbstractType* StoreStaticFieldComp::StaticType() const {
+ return value()->StaticType();
}
-RawAbstractType* BooleanNegateComp::CompileType() const {
+RawAbstractType* BooleanNegateComp::StaticType() const {
return Type::BoolInterface();
}
-RawAbstractType* InstanceOfComp::CompileType() const {
+RawAbstractType* InstanceOfComp::StaticType() const {
return Type::BoolInterface();
}
-RawAbstractType* CreateArrayComp::CompileType() const {
- // TODO(regis): Be more specific.
- return Type::DynamicType();
+RawAbstractType* CreateArrayComp::StaticType() const {
+ UNREACHABLE();
+ return AbstractType::null();
}
-RawAbstractType* CreateClosureComp::CompileType() const {
+RawAbstractType* CreateClosureComp::StaticType() const {
const Function& fun = function();
const Class& signature_class = Class::Handle(fun.signature_class());
return signature_class.SignatureType();
}
-RawAbstractType* AllocateObjectComp::CompileType() const {
+RawAbstractType* AllocateObjectComp::StaticType() const {
// TODO(regis): Be more specific.
return Type::DynamicType();
}
-RawAbstractType* AllocateObjectWithBoundsCheckComp::CompileType() const {
- // TODO(regis): Be more specific.
- return Type::DynamicType();
+RawAbstractType* AllocateObjectWithBoundsCheckComp::StaticType() const {
+ UNREACHABLE();
+ return AbstractType::null();
}
-RawAbstractType* LoadVMFieldComp::CompileType() const {
- // Type may be null if the field is a VM field, e.g. context parent.
+RawAbstractType* LoadVMFieldComp::StaticType() const {
+ ASSERT(!type().IsNull());
return type().raw();
}
-RawAbstractType* StoreVMFieldComp::CompileType() const {
- return value()->CompileType();
+RawAbstractType* StoreVMFieldComp::StaticType() const {
+ return value()->StaticType();
}
-RawAbstractType* InstantiateTypeArgumentsComp::CompileType() const {
+RawAbstractType* InstantiateTypeArgumentsComp::StaticType() const {
+ UNREACHABLE();
return AbstractType::null();
}
-RawAbstractType* ExtractConstructorTypeArgumentsComp::CompileType() const {
+RawAbstractType* ExtractConstructorTypeArgumentsComp::StaticType() const {
+ UNREACHABLE();
return AbstractType::null();
}
-RawAbstractType* ExtractConstructorInstantiatorComp::CompileType() const {
+RawAbstractType* ExtractConstructorInstantiatorComp::StaticType() const {
+ UNREACHABLE();
return AbstractType::null();
}
-RawAbstractType* AllocateContextComp::CompileType() const {
+RawAbstractType* AllocateContextComp::StaticType() const {
+ UNREACHABLE();
return AbstractType::null();
}
-RawAbstractType* ChainContextComp::CompileType() const {
+RawAbstractType* ChainContextComp::StaticType() const {
+ UNREACHABLE();
return AbstractType::null();
}
-RawAbstractType* CloneContextComp::CompileType() const {
+RawAbstractType* CloneContextComp::StaticType() const {
+ UNREACHABLE();
return AbstractType::null();
}
-RawAbstractType* CatchEntryComp::CompileType() const {
+RawAbstractType* CatchEntryComp::StaticType() const {
+ UNREACHABLE();
return AbstractType::null();
}
-RawAbstractType* CheckStackOverflowComp::CompileType() const {
- return Type::VoidType();
+RawAbstractType* CheckStackOverflowComp::StaticType() const {
+ UNREACHABLE();
+ return AbstractType::null();
}
-RawAbstractType* BinaryOpComp::CompileType() const {
+RawAbstractType* BinaryOpComp::StaticType() const {
// TODO(srdjan): Compute based on input types (ICData).
return Type::DynamicType();
}
-RawAbstractType* DoubleBinaryOpComp::CompileType() const {
+RawAbstractType* DoubleBinaryOpComp::StaticType() const {
return Type::DoubleInterface();
}
-RawAbstractType* UnarySmiOpComp::CompileType() const {
+RawAbstractType* UnarySmiOpComp::StaticType() const {
return Type::IntInterface();
}
-RawAbstractType* NumberNegateComp::CompileType() const {
+RawAbstractType* NumberNegateComp::StaticType() const {
return Type::NumberInterface();
}
-RawAbstractType* ToDoubleComp::CompileType() const {
+RawAbstractType* ToDoubleComp::StaticType() const {
return Type::DoubleInterface();
}
@@ -1048,13 +1031,11 @@
void AssertAssignableComp::EmitNativeCode(FlowGraphCompiler* compiler) {
- if (!IsEliminated()) {
- compiler->GenerateAssertAssignable(deopt_id(),
- token_pos(),
- try_index(),
- dst_type(),
- dst_name());
- }
+ compiler->GenerateAssertAssignable(deopt_id(),
+ token_pos(),
+ try_index(),
+ dst_type(),
+ dst_name());
ASSERT(locs()->in(0).reg() == locs()->out().reg());
}
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/object.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698