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

Side by Side Diff: vm/flow_graph_optimizer.cc

Issue 10833068: Refactor building arguments for InstanceCall and fix deoptimization environment for pushed argument… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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/flow_graph_builder.h" 7 #include "vm/flow_graph_builder.h"
8 #include "vm/il_printer.h" 8 #include "vm/il_printer.h"
9 #include "vm/object_store.h" 9 #include "vm/object_store.h"
10 10
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 return ICDataHasReceiverClassId(ic_data, kDouble); 107 return ICDataHasReceiverClassId(ic_data, kDouble);
108 } 108 }
109 109
110 110
111 static bool HasOnlyTwoDouble(const ICData& ic_data) { 111 static bool HasOnlyTwoDouble(const ICData& ic_data) {
112 return (ic_data.NumberOfChecks() == 1) && 112 return (ic_data.NumberOfChecks() == 1) &&
113 ICDataHasReceiverArgumentClassIds(ic_data, kDouble, kDouble); 113 ICDataHasReceiverArgumentClassIds(ic_data, kDouble, kDouble);
114 } 114 }
115 115
116 116
117 static void RemovePushArguments(InstanceCallComp* comp) {
118 // Remove original push arguments.
119 for (intptr_t i = 0; i < comp->ArgumentCount(); ++i) {
120 comp->ArgumentAt(i)->RemoveFromGraph();
121 }
122 }
123
124
117 bool FlowGraphOptimizer::TryReplaceWithBinaryOp(BindInstr* instr, 125 bool FlowGraphOptimizer::TryReplaceWithBinaryOp(BindInstr* instr,
118 InstanceCallComp* comp, 126 InstanceCallComp* comp,
119 Token::Kind op_kind) { 127 Token::Kind op_kind) {
120 BinaryOpComp::OperandsType operands_type = BinaryOpComp::kDynamicOperands; 128 BinaryOpComp::OperandsType operands_type = BinaryOpComp::kDynamicOperands;
121 ASSERT(comp->HasICData()); 129 ASSERT(comp->HasICData());
122 const ICData& ic_data = *comp->ic_data(); 130 const ICData& ic_data = *comp->ic_data();
123 switch (op_kind) { 131 switch (op_kind) {
124 case Token::kADD: 132 case Token::kADD:
125 case Token::kSUB: 133 case Token::kSUB:
126 case Token::kMUL: 134 case Token::kMUL:
(...skipping 29 matching lines...) Expand all
156 if (HasOnlyTwoSmi(ic_data)) { 164 if (HasOnlyTwoSmi(ic_data)) {
157 operands_type = BinaryOpComp::kSmiOperands; 165 operands_type = BinaryOpComp::kSmiOperands;
158 } else { 166 } else {
159 return false; 167 return false;
160 } 168 }
161 break; 169 break;
162 default: 170 default:
163 UNREACHABLE(); 171 UNREACHABLE();
164 }; 172 };
165 173
166 ASSERT(comp->InputCount() == 2); 174 ASSERT(comp->ArgumentCount() == 2);
167 Value* left = comp->InputAt(0); 175 Value* left = comp->ArgumentAt(0)->value();
168 Value* right = comp->InputAt(1); 176 Value* right = comp->ArgumentAt(1)->value();
169 BinaryOpComp* bin_op = 177 BinaryOpComp* bin_op =
170 new BinaryOpComp(op_kind, 178 new BinaryOpComp(op_kind,
171 operands_type, 179 operands_type,
172 comp, 180 comp,
173 left, 181 left,
174 right); 182 right);
175 bin_op->set_ic_data(comp->ic_data()); 183 bin_op->set_ic_data(comp->ic_data());
176 instr->set_computation(bin_op); 184 instr->set_computation(bin_op);
185 RemovePushArguments(comp);
177 return true; 186 return true;
178 } 187 }
179 188
180 189
181 bool FlowGraphOptimizer::TryReplaceWithUnaryOp(BindInstr* instr, 190 bool FlowGraphOptimizer::TryReplaceWithUnaryOp(BindInstr* instr,
182 InstanceCallComp* comp, 191 InstanceCallComp* comp,
183 Token::Kind op_kind) { 192 Token::Kind op_kind) {
184 if (comp->ic_data()->NumberOfChecks() != 1) { 193 if (comp->ic_data()->NumberOfChecks() != 1) {
185 // TODO(srdjan): Not yet supported. 194 // TODO(srdjan): Not yet supported.
186 return false; 195 return false;
187 } 196 }
188 ASSERT(comp->InputCount() == 1); 197 ASSERT(comp->ArgumentCount() == 1);
189 Computation* unary_op = NULL; 198 Computation* unary_op = NULL;
190 if (HasOneSmi(*comp->ic_data())) { 199 if (HasOneSmi(*comp->ic_data())) {
191 unary_op = new UnarySmiOpComp(op_kind, comp, comp->InputAt(0)); 200 unary_op = new UnarySmiOpComp(op_kind, comp, comp->ArgumentAt(0)->value());
192 } else if (HasOneDouble(*comp->ic_data()) && (op_kind == Token::kNEGATE)) { 201 } else if (HasOneDouble(*comp->ic_data()) && (op_kind == Token::kNEGATE)) {
193 unary_op = new NumberNegateComp(comp, comp->InputAt(0)); 202 unary_op = new NumberNegateComp(comp, comp->ArgumentAt(0)->value());
194 } 203 }
195 if (unary_op != NULL) { 204 if (unary_op == NULL) return false;
196 unary_op->set_ic_data(comp->ic_data()); 205
197 instr->set_computation(unary_op); 206 unary_op->set_ic_data(comp->ic_data());
198 return true; 207 instr->set_computation(unary_op);
199 } 208 RemovePushArguments(comp);
200 return false; 209 return true;
201 } 210 }
202 211
203 212
204 // Returns true if all targets are the same. 213 // Returns true if all targets are the same.
205 // TODO(srdjan): if targets are native use their C_function to compare. 214 // TODO(srdjan): if targets are native use their C_function to compare.
206 static bool HasOneTarget(const ICData& ic_data) { 215 static bool HasOneTarget(const ICData& ic_data) {
207 ASSERT(ic_data.NumberOfChecks() > 0); 216 ASSERT(ic_data.NumberOfChecks() > 0);
208 const Function& first_target = Function::Handle(ic_data.GetTargetAt(0)); 217 const Function& first_target = Function::Handle(ic_data.GetTargetAt(0));
209 Function& test_target = Function::Handle(); 218 Function& test_target = Function::Handle();
210 for (intptr_t i = 1; i < ic_data.NumberOfChecks(); i++) { 219 for (intptr_t i = 1; i < ic_data.NumberOfChecks(); i++) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 if (!HasOneTarget(ic_data)) { 259 if (!HasOneTarget(ic_data)) {
251 // TODO(srdjan): Implement for mutiple targets. 260 // TODO(srdjan): Implement for mutiple targets.
252 return false; 261 return false;
253 } 262 }
254 // Inline implicit instance getter. 263 // Inline implicit instance getter.
255 const String& field_name = 264 const String& field_name =
256 String::Handle(Field::NameFromGetter(comp->function_name())); 265 String::Handle(Field::NameFromGetter(comp->function_name()));
257 const Field& field = Field::Handle(GetField(class_ids[0], field_name)); 266 const Field& field = Field::Handle(GetField(class_ids[0], field_name));
258 ASSERT(!field.IsNull()); 267 ASSERT(!field.IsNull());
259 LoadInstanceFieldComp* load = new LoadInstanceFieldComp( 268 LoadInstanceFieldComp* load = new LoadInstanceFieldComp(
260 field, comp->InputAt(0), comp); 269 field, comp->ArgumentAt(0)->value(), comp);
261 load->set_ic_data(comp->ic_data()); 270 load->set_ic_data(comp->ic_data());
262 instr->set_computation(load); 271 instr->set_computation(load);
272 RemovePushArguments(comp);
263 return true; 273 return true;
264 } 274 }
265 275
266 // Not an implicit getter. 276 // Not an implicit getter.
267 MethodRecognizer::Kind recognized_kind = 277 MethodRecognizer::Kind recognized_kind =
268 MethodRecognizer::RecognizeKind(target); 278 MethodRecognizer::RecognizeKind(target);
269 279
270 // VM objects length getter. 280 // VM objects length getter.
271 if ((recognized_kind == MethodRecognizer::kObjectArrayLength) || 281 if ((recognized_kind == MethodRecognizer::kObjectArrayLength) ||
272 (recognized_kind == MethodRecognizer::kImmutableArrayLength) || 282 (recognized_kind == MethodRecognizer::kImmutableArrayLength) ||
273 (recognized_kind == MethodRecognizer::kGrowableArrayLength)) { 283 (recognized_kind == MethodRecognizer::kGrowableArrayLength)) {
274 if (!HasOneTarget(ic_data)) { 284 if (!HasOneTarget(ic_data)) {
275 // TODO(srdjan): Implement for mutiple targets. 285 // TODO(srdjan): Implement for mutiple targets.
276 return false; 286 return false;
277 } 287 }
278 intptr_t length_offset = -1; 288 intptr_t length_offset = -1;
279 switch (recognized_kind) { 289 switch (recognized_kind) {
280 case MethodRecognizer::kObjectArrayLength: 290 case MethodRecognizer::kObjectArrayLength:
281 case MethodRecognizer::kImmutableArrayLength: 291 case MethodRecognizer::kImmutableArrayLength:
282 length_offset = Array::length_offset(); 292 length_offset = Array::length_offset();
283 break; 293 break;
284 case MethodRecognizer::kGrowableArrayLength: 294 case MethodRecognizer::kGrowableArrayLength:
285 length_offset = GrowableObjectArray::length_offset(); 295 length_offset = GrowableObjectArray::length_offset();
286 break; 296 break;
287 default: 297 default:
288 UNREACHABLE(); 298 UNREACHABLE();
289 } 299 }
290 LoadVMFieldComp* load = new LoadVMFieldComp( 300 LoadVMFieldComp* load = new LoadVMFieldComp(
291 comp->InputAt(0), 301 comp->ArgumentAt(0)->value(),
292 length_offset, 302 length_offset,
293 Type::ZoneHandle(Type::IntInterface())); 303 Type::ZoneHandle(Type::IntInterface()));
294 load->set_original(comp); 304 load->set_original(comp);
295 load->set_ic_data(comp->ic_data()); 305 load->set_ic_data(comp->ic_data());
296 instr->set_computation(load); 306 instr->set_computation(load);
307 RemovePushArguments(comp);
297 return true; 308 return true;
298 } 309 }
299 310
300 if (recognized_kind == MethodRecognizer::kStringBaseLength) { 311 if (recognized_kind == MethodRecognizer::kStringBaseLength) {
301 if (!HasOneTarget(ic_data)) { 312 if (!HasOneTarget(ic_data)) {
302 // Target is not only StringBase_get_length. 313 // Target is not only StringBase_get_length.
303 return false; 314 return false;
304 } 315 }
305 ASSERT(HasOneTarget(ic_data)); 316 ASSERT(HasOneTarget(ic_data));
306 LoadVMFieldComp* load = new LoadVMFieldComp( 317 LoadVMFieldComp* load = new LoadVMFieldComp(
307 comp->InputAt(0), 318 comp->ArgumentAt(0)->value(),
308 String::length_offset(), 319 String::length_offset(),
309 Type::ZoneHandle(Type::IntInterface())); 320 Type::ZoneHandle(Type::IntInterface()));
310 load->set_original(comp); 321 load->set_original(comp);
311 load->set_ic_data(comp->ic_data()); 322 load->set_ic_data(comp->ic_data());
312 instr->set_computation(load); 323 instr->set_computation(load);
324 RemovePushArguments(comp);
313 return true; 325 return true;
314 } 326 }
315 return false; 327 return false;
316 } 328 }
317 329
318 330
319 // Inline only simple, frequently called core library methods. 331 // Inline only simple, frequently called core library methods.
320 bool FlowGraphOptimizer::TryInlineInstanceMethod(BindInstr* instr, 332 bool FlowGraphOptimizer::TryInlineInstanceMethod(BindInstr* instr,
321 InstanceCallComp* comp) { 333 InstanceCallComp* comp) {
322 ASSERT(comp->HasICData()); 334 ASSERT(comp->HasICData());
(...skipping 14 matching lines...) Expand all
337 } else if (recognized_kind == MethodRecognizer::kIntegerToDouble) { 349 } else if (recognized_kind == MethodRecognizer::kIntegerToDouble) {
338 from_kind = kSmi; 350 from_kind = kSmi;
339 } else { 351 } else {
340 return false; 352 return false;
341 } 353 }
342 354
343 if (class_ids[0] != from_kind) { 355 if (class_ids[0] != from_kind) {
344 return false; 356 return false;
345 } 357 }
346 ToDoubleComp* coerce = new ToDoubleComp( 358 ToDoubleComp* coerce = new ToDoubleComp(
347 comp->InputAt(0), from_kind, comp); 359 comp->ArgumentAt(0)->value(), from_kind, comp);
348 instr->set_computation(coerce); 360 instr->set_computation(coerce);
361 RemovePushArguments(comp);
349 return true; 362 return true;
350 } 363 }
351 364
352 365
353 366
354 367
355 void FlowGraphOptimizer::VisitInstanceCall(InstanceCallComp* comp, 368 void FlowGraphOptimizer::VisitInstanceCall(InstanceCallComp* comp,
356 BindInstr* instr) { 369 BindInstr* instr) {
357 if (comp->HasICData() && (comp->ic_data()->NumberOfChecks() > 0)) { 370 if (comp->HasICData() && (comp->ic_data()->NumberOfChecks() > 0)) {
358 const Token::Kind op_kind = comp->token_kind(); 371 const Token::Kind op_kind = comp->token_kind();
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
540 LocationSummary* locs = it.Current()->locs(); 553 LocationSummary* locs = it.Current()->locs();
541 if ((locs != NULL) && locs->is_call()) { 554 if ((locs != NULL) && locs->is_call()) {
542 is_leaf_ = false; 555 is_leaf_ = false;
543 return; 556 return;
544 } 557 }
545 } 558 }
546 } 559 }
547 } 560 }
548 561
549 } // namespace dart 562 } // namespace dart
OLDNEW
« vm/flow_graph_builder.cc ('K') | « vm/flow_graph_builder.cc ('k') | vm/il_printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698