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

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

Issue 12050002: Introduce InvokeMathCFunction that can be used to directly invoke mathematical function provided by… (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 11 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) 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/flow_graph_builder.h" 9 #include "vm/flow_graph_builder.h"
10 #include "vm/flow_graph_compiler.h" 10 #include "vm/flow_graph_compiler.h"
(...skipping 1256 matching lines...) Expand 10 before | Expand all | Expand 10 after
1267 index->Copy(), 1267 index->Copy(),
1268 cid, 1268 cid,
1269 call), 1269 call),
1270 call->env(), 1270 call->env(),
1271 Definition::kEffect); 1271 Definition::kEffect);
1272 } 1272 }
1273 return new LoadIndexedInstr(str, index, cid); 1273 return new LoadIndexedInstr(str, index, cid);
1274 } 1274 }
1275 1275
1276 1276
1277 void FlowGraphOptimizer::ReplaceWithMathCFunction(
1278 InstanceCallInstr* call,
1279 MethodRecognizer::Kind recognized_kind) {
1280 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy());
1281 ZoneGrowableArray<Value*>* args =
1282 new ZoneGrowableArray<Value*>(call->ArgumentCount());
1283 for (intptr_t i = 0; i < call->ArgumentCount(); i++) {
1284 args->Add(call->ArgumentAt(i)->value());
1285 }
1286 InvokeMathCFunctionInstr* invoke =
1287 new InvokeMathCFunctionInstr(args, call, recognized_kind);
1288 call->ReplaceWith(invoke, current_iterator());
1289 RemovePushArguments(call);
1290 }
1291
1292
1277 // Inline only simple, frequently called core library methods. 1293 // Inline only simple, frequently called core library methods.
1278 bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { 1294 bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) {
1279 ASSERT(call->HasICData()); 1295 ASSERT(call->HasICData());
1280 const ICData& ic_data = *call->ic_data(); 1296 const ICData& ic_data = *call->ic_data();
1281 if ((ic_data.NumberOfChecks() == 0) || !ic_data.HasOneTarget()) { 1297 if ((ic_data.NumberOfChecks() == 0) || !ic_data.HasOneTarget()) {
1282 // No type feedback collected or multiple targets found. 1298 // No type feedback collected or multiple targets found.
1283 return false; 1299 return false;
1284 } 1300 }
1285 Function& target = Function::Handle(); 1301 Function& target = Function::Handle();
1286 GrowableArray<intptr_t> class_ids; 1302 GrowableArray<intptr_t> class_ids;
(...skipping 27 matching lines...) Expand all
1314 if ((recognized_kind == MethodRecognizer::kIntegerToDouble) && 1330 if ((recognized_kind == MethodRecognizer::kIntegerToDouble) &&
1315 (class_ids[0] == kSmiCid)) { 1331 (class_ids[0] == kSmiCid)) {
1316 SmiToDoubleInstr* s2d_instr = new SmiToDoubleInstr(call); 1332 SmiToDoubleInstr* s2d_instr = new SmiToDoubleInstr(call);
1317 call->ReplaceWith(s2d_instr, current_iterator()); 1333 call->ReplaceWith(s2d_instr, current_iterator());
1318 // Pushed arguments are not removed because SmiToDouble is implemented 1334 // Pushed arguments are not removed because SmiToDouble is implemented
1319 // as a call. 1335 // as a call.
1320 return true; 1336 return true;
1321 } 1337 }
1322 1338
1323 if (class_ids[0] == kDoubleCid) { 1339 if (class_ids[0] == kDoubleCid) {
1324 if (recognized_kind == MethodRecognizer::kDoubleToInteger) { 1340 switch (recognized_kind) {
1325 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy()); 1341 case MethodRecognizer::kDoubleToInteger: {
1326 ASSERT(call->HasICData()); 1342 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy());
1327 const ICData& ic_data = *call->ic_data(); 1343 ASSERT(call->HasICData());
1328 Definition* d2i_instr = NULL; 1344 const ICData& ic_data = *call->ic_data();
1329 if (ic_data.deopt_reason() == kDeoptDoubleToSmi) { 1345 Definition* d2i_instr = NULL;
1330 // Do not repeatedly deoptimize because result didn't fit into Smi. 1346 if (ic_data.deopt_reason() == kDeoptDoubleToSmi) {
1331 d2i_instr = new DoubleToIntegerInstr(call->ArgumentAt(0)->value(), 1347 // Do not repeatedly deoptimize because result didn't fit into Smi.
1332 call); 1348 d2i_instr = new DoubleToIntegerInstr(call->ArgumentAt(0)->value(),
1333 } else { 1349 call);
1334 // Optimistically assume result fits into Smi. 1350 } else {
1335 d2i_instr = new DoubleToSmiInstr(call->ArgumentAt(0)->value(), call); 1351 // Optimistically assume result fits into Smi.
1352 d2i_instr = new DoubleToSmiInstr(call->ArgumentAt(0)->value(), call);
1353 }
1354 call->ReplaceWith(d2i_instr, current_iterator());
1355 RemovePushArguments(call);
1356 return true;
1336 } 1357 }
1337 call->ReplaceWith(d2i_instr, current_iterator()); 1358 case MethodRecognizer::kDoublePow: {
1338 RemovePushArguments(call); 1359 ReplaceWithMathCFunction(call, recognized_kind);
1339 return true; 1360 return true;
1340 } 1361 }
1341 if ((recognized_kind == MethodRecognizer::kDoubleTruncate) || 1362 case MethodRecognizer::kDoubleTruncate:
1342 (recognized_kind == MethodRecognizer::kDoubleRound) || 1363 case MethodRecognizer::kDoubleRound:
1343 (recognized_kind == MethodRecognizer::kDoubleFloor) || 1364 case MethodRecognizer::kDoubleFloor:
1344 (recognized_kind == MethodRecognizer::kDoubleCeil)) { 1365 case MethodRecognizer::kDoubleCeil: {
1345 if (!CPUFeatures::double_truncate_round_supported()) { 1366 if (!CPUFeatures::double_truncate_round_supported()) {
1367 ReplaceWithMathCFunction(call, recognized_kind);
1368 } else {
1369 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy());
1370 DoubleToDoubleInstr* d2d_instr =
1371 new DoubleToDoubleInstr(call->ArgumentAt(0)->value(),
1372 call,
1373 recognized_kind);
1374 call->ReplaceWith(d2d_instr, current_iterator());
1375 RemovePushArguments(call);
1376 }
1377 return true;
1378 }
Florian Schneider 2013/01/21 16:31:26 I'd add a comment for intended fall-through.
Vyacheslav Egorov (Google) 2013/01/21 16:50:08 There is no fall through. Removed curly braces for
1379 default:
1380 // Unsupported method.
1346 return false; 1381 return false;
1347 }
1348 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy());
1349 DoubleToDoubleInstr* d2d_instr =
1350 new DoubleToDoubleInstr(call->ArgumentAt(0)->value(),
1351 call,
1352 recognized_kind);
1353 call->ReplaceWith(d2d_instr, current_iterator());
1354 RemovePushArguments(call);
1355 return true;
1356 } 1382 }
1357 } 1383 }
1358 1384
1359 return false; 1385 return false;
1360 } 1386 }
1361 1387
1362 1388
1363 // Returns a Boolean constant if all classes in ic_data yield the same type-test 1389 // Returns a Boolean constant if all classes in ic_data yield the same type-test
1364 // result and the type tests do not depend on type arguments. Otherwise return 1390 // result and the type tests do not depend on type arguments. Otherwise return
1365 // Bool::null(). 1391 // Bool::null().
(...skipping 2962 matching lines...) Expand 10 before | Expand all | Expand 10 after
4328 SetValue(instr, non_constant_); 4354 SetValue(instr, non_constant_);
4329 } 4355 }
4330 4356
4331 4357
4332 void ConstantPropagator::VisitDoubleToDouble(DoubleToDoubleInstr* instr) { 4358 void ConstantPropagator::VisitDoubleToDouble(DoubleToDoubleInstr* instr) {
4333 // TODO(kmillikin): Handle conversion. 4359 // TODO(kmillikin): Handle conversion.
4334 SetValue(instr, non_constant_); 4360 SetValue(instr, non_constant_);
4335 } 4361 }
4336 4362
4337 4363
4364 void ConstantPropagator::VisitInvokeMathCFunction(
4365 InvokeMathCFunctionInstr* instr) {
4366 // TODO(kmillikin): Handle conversion.
4367 SetValue(instr, non_constant_);
4368 }
4369
4338 void ConstantPropagator::VisitConstant(ConstantInstr* instr) { 4370 void ConstantPropagator::VisitConstant(ConstantInstr* instr) {
4339 SetValue(instr, instr->value()); 4371 SetValue(instr, instr->value());
4340 } 4372 }
4341 4373
4342 4374
4343 void ConstantPropagator::VisitConstraint(ConstraintInstr* instr) { 4375 void ConstantPropagator::VisitConstraint(ConstraintInstr* instr) {
4344 // Should not be used outside of range analysis. 4376 // Should not be used outside of range analysis.
4345 UNREACHABLE(); 4377 UNREACHABLE();
4346 } 4378 }
4347 4379
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
4555 4587
4556 if (FLAG_trace_constant_propagation) { 4588 if (FLAG_trace_constant_propagation) {
4557 OS::Print("\n==== After constant propagation ====\n"); 4589 OS::Print("\n==== After constant propagation ====\n");
4558 FlowGraphPrinter printer(*graph_); 4590 FlowGraphPrinter printer(*graph_);
4559 printer.PrintBlocks(); 4591 printer.PrintBlocks();
4560 } 4592 }
4561 } 4593 }
4562 4594
4563 4595
4564 } // namespace dart 4596 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698