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

Unified Diff: runtime/vm/intermediate_language.cc

Issue 10830109: Add type propagation phase in optimizing compiler (work in progress). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 5 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/isolate.h » ('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 10124)
+++ runtime/vm/intermediate_language.cc (working copy)
@@ -116,6 +116,68 @@
}
+// Returns true if the static type of this value is more specific than the
+// given dst_type.
+// 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.
+
+ // If the value is the null constant, its type (NullType) is more specific
+ // than the destination type, even if the destination type is the void type,
+ // since a void function is allowed to return null.
+ if (IsConstant() && AsConstant()->value().IsNull()) {
+ return true;
+ }
+
+ // Functions that do not explicitly return a value, implicitly return null,
+ // except generative constructors, which return the object being constructed.
+ // It is therefore acceptable for void functions to return null.
+ // In case of a null constant, we have already returned true above, else we
+ // return false here.
+ if (dst_type.IsVoidType()) {
+ return false;
+ }
+
+ // Consider the static type of the value.
+ const AbstractType& static_type = AbstractType::Handle(StaticType());
+ ASSERT(!static_type.IsMalformed());
+
+ // 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 (static_type.IsVoidType()) {
+ return true;
+ }
+
+ // 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
+ // encounter the 2 sentinel values. The type check of a sentinel value
+ // 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 (static_type.IsNullType()) {
+ return true;
+ }
+
+ // The run time type of the value is guaranteed to be a subtype of the
+ // 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 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 static type, is also guaranteed to be
+ // a subtype of the destination type and the type check can therefore be
+ // eliminated.
+ return static_type.IsMoreSpecificThan(dst_type, NULL);
+}
+
+
intptr_t AllocateObjectComp::InputCount() const {
return arguments().length();
}
@@ -327,7 +389,26 @@
RawAbstractType* PhiInstr::StaticType() const {
// TODO(regis): Return the least upper bound of the input static types.
- return Type::DynamicType();
+ // 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 = 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 {
+ // The types are unrelated. No need to continue.
+ least_specific_type = Type::ObjectType();
+ break;
+ }
+ }
+ return least_specific_type.raw();
}
@@ -825,8 +906,8 @@
RawAbstractType* AllocateObjectComp::StaticType() const {
- UNREACHABLE();
- return AbstractType::null();
+ // TODO(regis): Be more specific.
+ return Type::DynamicType();
}
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/isolate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698