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

Side by Side Diff: runtime/vm/flow_graph_optimizer.cc

Issue 104893003: For instance call representing numerical comparisons (double and Smi for now) that were never visit… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/flow_graph_optimizer.h" 5 #include "vm/flow_graph_optimizer.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/cha.h" 8 #include "vm/cha.h"
9 #include "vm/dart_entry.h" 9 #include "vm/dart_entry.h"
10 #include "vm/flow_graph_builder.h" 10 #include "vm/flow_graph_builder.h"
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 return FLAG_enable_simd_inline; 55 return FLAG_enable_simd_inline;
56 } 56 }
57 57
58 58
59 // Optimize instance calls using ICData. 59 // Optimize instance calls using ICData.
60 void FlowGraphOptimizer::ApplyICData() { 60 void FlowGraphOptimizer::ApplyICData() {
61 VisitBlocks(); 61 VisitBlocks();
62 } 62 }
63 63
64 64
65 // Optimize instance calls using cid. 65 // Optimize instance calls using cid. This is called after the optimizer which
66 // converts instance calls to instructions has been run. Any remaining
67 // instance calls probably do not have IC data.
66 // Attempts to convert an instance call (IC call) using propagated class-ids, 68 // Attempts to convert an instance call (IC call) using propagated class-ids,
67 // e.g., receiver class id, guarded-cid. 69 // e.g., receiver class id, guarded-cid.
68 void FlowGraphOptimizer::ApplyClassIds() { 70 void FlowGraphOptimizer::ApplyClassIds() {
69 ASSERT(current_iterator_ == NULL); 71 ASSERT(current_iterator_ == NULL);
70 for (intptr_t i = 0; i < block_order_.length(); ++i) { 72 for (intptr_t i = 0; i < block_order_.length(); ++i) {
71 BlockEntryInstr* entry = block_order_[i]; 73 BlockEntryInstr* entry = block_order_[i];
72 ForwardInstructionIterator it(entry); 74 ForwardInstructionIterator it(entry);
73 current_iterator_ = &it; 75 current_iterator_ = &it;
74 for (; !it.Done(); it.Advance()) { 76 for (; !it.Done(); it.Advance()) {
75 Instruction* instr = it.Current(); 77 Instruction* instr = it.Current();
(...skipping 13 matching lines...) Expand all
89 if (compare->IsStrictCompare()) { 91 if (compare->IsStrictCompare()) {
90 VisitStrictCompare(compare->AsStrictCompare()); 92 VisitStrictCompare(compare->AsStrictCompare());
91 } 93 }
92 } 94 }
93 } 95 }
94 current_iterator_ = NULL; 96 current_iterator_ = NULL;
95 } 97 }
96 } 98 }
97 99
98 100
101 // TODO(srdjan): write tests for others.
102 static bool IsNumberCid(intptr_t cid) {
103 return (cid == kSmiCid) || (cid == kDoubleCid);
104 }
105
106
99 // Attempt to build ICData for call using propagated class-ids. 107 // Attempt to build ICData for call using propagated class-ids.
100 bool FlowGraphOptimizer::TryCreateICData(InstanceCallInstr* call) { 108 bool FlowGraphOptimizer::TryCreateICData(InstanceCallInstr* call) {
101 ASSERT(call->HasICData()); 109 ASSERT(call->HasICData());
102 if (call->ic_data()->NumberOfChecks() > 0) { 110 if (call->ic_data()->NumberOfChecks() > 0) {
103 // This occurs when an instance call has too many checks. 111 // This occurs when an instance call has too many checks, will be
104 // TODO(srdjan): Replace IC call with megamorphic call. 112 // converted to megamorphic calls.
105 return false; 113 return false;
106 } 114 }
107 GrowableArray<intptr_t> class_ids(call->ic_data()->num_args_tested()); 115 GrowableArray<intptr_t> class_ids(call->ic_data()->num_args_tested());
108 ASSERT(call->ic_data()->num_args_tested() <= call->ArgumentCount()); 116 ASSERT(call->ic_data()->num_args_tested() <= call->ArgumentCount());
109 for (intptr_t i = 0; i < call->ic_data()->num_args_tested(); i++) { 117 for (intptr_t i = 0; i < call->ic_data()->num_args_tested(); i++) {
110 intptr_t cid = call->PushArgumentAt(i)->value()->Type()->ToCid(); 118 intptr_t cid = call->PushArgumentAt(i)->value()->Type()->ToCid();
111 class_ids.Add(cid); 119 class_ids.Add(cid);
112 } 120 }
113 // TODO(srdjan): Test for number of arguments checked greater than 1. 121 // Only one or two checked arguments are handled at the moment.
114 if (class_ids.length() != 1) { 122 if (class_ids.length() == 2) {
123 // We guess that comparison and binary operations typically
124 // have both arguments of the same cid. If only one argument's cid is known,
125 // assume the other argument has the same cid.
126 const Token::Kind op_kind = call->token_kind();
127 if (!Token::IsRelationalOperator(op_kind) &&
128 !Token::IsEqualityOperator(op_kind) &&
129 !Token::IsBinaryOperator(op_kind)) {
130 return false;
131 }
132 // If left or right is a number -> make the other .
133 const intptr_t cid_0 = class_ids[0];
134 const intptr_t cid_1 = class_ids[1];
135 if ((cid_0 == kDynamicCid) && (IsNumberCid(cid_1))) {
136 class_ids[0] = cid_1;
137 } else if (IsNumberCid(cid_0) && (cid_1 == kDynamicCid)) {
138 class_ids[1] = cid_0;
139 } else {
140 return false;
141 }
142 } else if (class_ids.length() != 1) {
115 return false; 143 return false;
116 } 144 }
117 if (class_ids[0] != kDynamicCid) { 145 if (class_ids[0] != kDynamicCid) {
118 ArgumentsDescriptor args_desc( 146 ArgumentsDescriptor args_desc(
119 Array::Handle(ArgumentsDescriptor::New(call->ArgumentCount(), 147 Array::Handle(ArgumentsDescriptor::New(call->ArgumentCount(),
120 call->argument_names()))); 148 call->argument_names())));
121 const Class& receiver_class = Class::Handle( 149 const Class& receiver_class = Class::Handle(
122 Isolate::Current()->class_table()->At(class_ids[0])); 150 Isolate::Current()->class_table()->At(class_ids[0]));
123 const Function& function = Function::Handle( 151 const Function& function = Function::Handle(
124 Resolver::ResolveDynamicForReceiverClass( 152 Resolver::ResolveDynamicForReceiverClass(
125 receiver_class, 153 receiver_class,
126 call->function_name(), 154 call->function_name(),
127 args_desc)); 155 args_desc));
128 if (function.IsNull()) { 156 if (function.IsNull()) {
129 return false; 157 return false;
130 } 158 }
131 // Create new ICData, do not modify the one attached to the instruction
132 // since it is attached to the assembly instruction itself.
133 // TODO(srdjan): Prevent modification of ICData object that is
134 // referenced in assembly code.
135 ICData& ic_data = ICData::ZoneHandle(ICData::New( 159 ICData& ic_data = ICData::ZoneHandle(ICData::New(
136 flow_graph_->parsed_function().function(), 160 flow_graph_->parsed_function().function(),
137 call->function_name(), 161 call->function_name(),
138 Object::empty_array(), // Dummy argument descriptor. 162 Object::empty_array(), // Dummy argument descriptor.
139 call->deopt_id(), 163 call->deopt_id(),
140 class_ids.length())); 164 class_ids.length()));
141 ic_data.AddReceiverCheck(class_ids[0], function); 165 if (class_ids.length() == 1) {
166 ic_data.AddReceiverCheck(class_ids[0], function);
167 } else {
168 ic_data.AddCheck(class_ids, function);
169 }
142 call->set_ic_data(&ic_data); 170 call->set_ic_data(&ic_data);
143 return true; 171 return true;
144 } 172 }
145 return false; 173 return false;
146 } 174 }
147 175
148 176
149 static const ICData& SpecializeICData(const ICData& ic_data, intptr_t cid) { 177 static const ICData& SpecializeICData(const ICData& ic_data, intptr_t cid) {
150 ASSERT(ic_data.num_args_tested() == 1); 178 ASSERT(ic_data.num_args_tested() == 1);
151 179
(...skipping 7893 matching lines...) Expand 10 before | Expand all | Expand 10 after
8045 } 8073 }
8046 8074
8047 // Insert materializations at environment uses. 8075 // Insert materializations at environment uses.
8048 for (intptr_t i = 0; i < exits.length(); i++) { 8076 for (intptr_t i = 0; i < exits.length(); i++) {
8049 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); 8077 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields);
8050 } 8078 }
8051 } 8079 }
8052 8080
8053 8081
8054 } // namespace dart 8082 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698