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

Unified Diff: runtime/vm/flow_graph_optimizer.cc

Issue 11746024: Optimize instanceof: if all results are true and tests can be done using class only replace instanc… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 12 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/flow_graph_optimizer.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/flow_graph_optimizer.cc
===================================================================
--- runtime/vm/flow_graph_optimizer.cc (revision 16619)
+++ runtime/vm/flow_graph_optimizer.cc (working copy)
@@ -1249,6 +1249,41 @@
}
+// Returns a Boolean constant if all classes in ic_data yield the same type-test
+// result and the type tests do not depend on type arguments. Otherwise return
+// Bool::null().
+RawBool* FlowGraphOptimizer::InstanceOfAsBool(const ICData& ic_data,
+ const AbstractType& type) const {
+ ASSERT(ic_data.num_args_tested() == 1); // Unary checks only.
+ if (!type.IsInstantiated() || type.IsMalformed()) return Bool::null();
+ const Class& type_class = Class::Handle(type.type_class());
+ if (type_class.HasTypeArguments()) return Bool::null();
+ const ClassTable& class_table = *Isolate::Current()->class_table();
+ Bool& prev = Bool::Handle();
+ Class& cls = Class::Handle();
+ for (int i = 0; i < ic_data.NumberOfChecks(); i++) {
+ cls = class_table.At(ic_data.GetReceiverClassIdAt(i));
+ if (cls.HasTypeArguments()) return Bool::null();
+ // TODO(regis): Fix Class::TypeTest to support NullClass.
regis 2013/01/04 01:39:16 I am pretty sure that Class::TypeTest is supportin
srdjan 2013/01/04 21:10:25 Removed TODO. Discussed off-line changes to Class:
+ bool is_subtype = false;
+ if (cls.IsNullClass()) {
+ is_subtype = type_class.IsDynamicClass() || type_class.IsObjectClass();
+ } else {
+ is_subtype = cls.IsSubtypeOf(TypeArguments::Handle(),
+ type_class,
+ TypeArguments::Handle(),
+ NULL);
+ }
+ if (prev.IsNull()) {
+ prev = is_subtype ? Bool::True() : Bool::False();
+ } else {
+ if (is_subtype != prev.value()) return Bool::null();
+ }
+ }
+ return prev.raw();
+}
+
+
// TODO(srdjan): Use ICData to check if always true or false.
void FlowGraphOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) {
ASSERT(Token::IsTypeTestOperator(call->token_kind()));
@@ -1259,6 +1294,21 @@
AbstractType::Cast(call->ArgumentAt(3)->value()->BoundConstant());
const Bool& negate =
Florian Schneider 2013/01/04 11:35:41 Maybe just bool negate = Bool::Cast(call->Argum
srdjan 2013/01/04 21:10:25 Done.
Bool::Cast(call->ArgumentAt(4)->value()->BoundConstant());
+ const ICData& unary_checks =
+ ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecks());
+ if (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks) {
+ Bool& as_bool = Bool::ZoneHandle(InstanceOfAsBool(unary_checks, type));
+ if (!as_bool.IsNull()) {
+ AddCheckClass(call, left_val->Copy());
+ if (negate.value()) {
+ as_bool = as_bool.value() ? Bool::False() : Bool::True();
+ }
+ ConstantInstr* bool_const = new ConstantInstr(as_bool);
+ call->ReplaceWith(bool_const, current_iterator());
+ RemovePushArguments(call);
+ return;
+ }
+ }
InstanceOfInstr* instance_of =
new InstanceOfInstr(call->token_pos(),
left_val,
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698