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

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

Issue 513213002: Generate some intrinsics using our IR. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 3 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/globals.h" // Needed here to get TARGET_ARCH_XXX. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_XXX.
6 6
7 #include "vm/flow_graph_compiler.h" 7 #include "vm/flow_graph_compiler.h"
8 8
9 #include "vm/bit_vector.h" 9 #include "vm/bit_vector.h"
10 #include "vm/cha.h" 10 #include "vm/cha.h"
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 exception_handlers_list_(NULL), 91 exception_handlers_list_(NULL),
92 pc_descriptors_list_(NULL), 92 pc_descriptors_list_(NULL),
93 stackmap_table_builder_( 93 stackmap_table_builder_(
94 is_optimizing ? new StackmapTableBuilder() : NULL), 94 is_optimizing ? new StackmapTableBuilder() : NULL),
95 block_info_(block_order_.length()), 95 block_info_(block_order_.length()),
96 deopt_infos_(), 96 deopt_infos_(),
97 static_calls_target_table_(GrowableObjectArray::ZoneHandle( 97 static_calls_target_table_(GrowableObjectArray::ZoneHandle(
98 GrowableObjectArray::New())), 98 GrowableObjectArray::New())),
99 is_optimizing_(is_optimizing), 99 is_optimizing_(is_optimizing),
100 may_reoptimize_(false), 100 may_reoptimize_(false),
101 intrinsic_mode_(false),
101 double_class_(Class::ZoneHandle( 102 double_class_(Class::ZoneHandle(
102 isolate_->object_store()->double_class())), 103 isolate_->object_store()->double_class())),
103 mint_class_(Class::ZoneHandle( 104 mint_class_(Class::ZoneHandle(
104 isolate_->object_store()->mint_class())), 105 isolate_->object_store()->mint_class())),
105 float32x4_class_(Class::ZoneHandle( 106 float32x4_class_(Class::ZoneHandle(
106 isolate_->object_store()->float32x4_class())), 107 isolate_->object_store()->float32x4_class())),
107 float64x2_class_(Class::ZoneHandle( 108 float64x2_class_(Class::ZoneHandle(
108 isolate_->object_store()->float64x2_class())), 109 isolate_->object_store()->float64x2_class())),
109 int32x4_class_(Class::ZoneHandle( 110 int32x4_class_(Class::ZoneHandle(
110 isolate_->object_store()->int32x4_class())), 111 isolate_->object_store()->int32x4_class())),
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
540 ASSERT(Code::kSCallTableFunctionEntry == 1); 541 ASSERT(Code::kSCallTableFunctionEntry == 1);
541 static_calls_target_table_.Add(func); 542 static_calls_target_table_.Add(func);
542 ASSERT(Code::kSCallTableCodeEntry == 2); 543 ASSERT(Code::kSCallTableCodeEntry == 2);
543 static_calls_target_table_.Add(Code::Handle()); 544 static_calls_target_table_.Add(Code::Handle());
544 } 545 }
545 546
546 547
547 void FlowGraphCompiler::AddDeoptIndexAtCall(intptr_t deopt_id, 548 void FlowGraphCompiler::AddDeoptIndexAtCall(intptr_t deopt_id,
548 intptr_t token_pos) { 549 intptr_t token_pos) {
549 ASSERT(is_optimizing()); 550 ASSERT(is_optimizing());
551 ASSERT(!intrinsic_mode());
550 CompilerDeoptInfo* info = 552 CompilerDeoptInfo* info =
551 new CompilerDeoptInfo(deopt_id, 553 new CompilerDeoptInfo(deopt_id,
552 ICData::kDeoptAtCall, 554 ICData::kDeoptAtCall,
553 pending_deoptimization_env_); 555 pending_deoptimization_env_);
554 info->set_pc_offset(assembler()->CodeSize()); 556 info->set_pc_offset(assembler()->CodeSize());
555 deopt_infos_.Add(info); 557 deopt_infos_.Add(info);
556 } 558 }
557 559
558 560
559 // This function must be in sync with FlowGraphCompiler::SaveLiveRegisters 561 // This function must be in sync with FlowGraphCompiler::SaveLiveRegisters
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 cpu_reg_slots); 722 cpu_reg_slots);
721 } 723 }
722 } 724 }
723 } 725 }
724 return env; 726 return env;
725 } 727 }
726 728
727 729
728 Label* FlowGraphCompiler::AddDeoptStub(intptr_t deopt_id, 730 Label* FlowGraphCompiler::AddDeoptStub(intptr_t deopt_id,
729 ICData::DeoptReasonId reason) { 731 ICData::DeoptReasonId reason) {
732 if (intrinsic_mode()) return &intrinsic_deopt_label_;
srdjan 2014/09/02 18:48:21 This feels fragile as we must guaranteed that the
Florian Schneider 2014/09/02 21:03:20 Can you elaborate? There is only one instance of F
srdjan 2014/09/08 17:34:06 I was mainly worried that the lifetime of a FlowGr
733
730 ASSERT(is_optimizing_); 734 ASSERT(is_optimizing_);
731 CompilerDeoptInfoWithStub* stub = 735 CompilerDeoptInfoWithStub* stub =
732 new CompilerDeoptInfoWithStub(deopt_id, 736 new CompilerDeoptInfoWithStub(deopt_id,
733 reason, 737 reason,
734 pending_deoptimization_env_); 738 pending_deoptimization_env_);
735 deopt_infos_.Add(stub); 739 deopt_infos_.Add(stub);
736 return stub->entry_label(); 740 return stub->entry_label();
737 } 741 }
738 742
739 743
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
848 ASSERT(sequence_node.NodeAt(0)->IsStoreInstanceFieldNode()); 852 ASSERT(sequence_node.NodeAt(0)->IsStoreInstanceFieldNode());
849 ASSERT(sequence_node.NodeAt(1)->IsReturnNode()); 853 ASSERT(sequence_node.NodeAt(1)->IsReturnNode());
850 const StoreInstanceFieldNode& store_node = 854 const StoreInstanceFieldNode& store_node =
851 *sequence_node.NodeAt(0)->AsStoreInstanceFieldNode(); 855 *sequence_node.NodeAt(0)->AsStoreInstanceFieldNode();
852 if (store_node.field().guarded_cid() == kDynamicCid) { 856 if (store_node.field().guarded_cid() == kDynamicCid) {
853 GenerateInlinedSetter(store_node.field().Offset()); 857 GenerateInlinedSetter(store_node.field().Offset());
854 return; 858 return;
855 } 859 }
856 } 860 }
857 } 861 }
858 // Even if an intrinsified version of the function was successfully 862
859 // generated, it may fall through to the non-intrinsified method body. 863 EnterIntrinsicMode();
860 Intrinsifier::Intrinsify(parsed_function().function(), assembler()); 864
865 Intrinsifier::Intrinsify(parsed_function(), this);
866
867 ExitIntrinsicMode();
868 // "Deoptimization" from intrinsic continues here.
srdjan 2014/09/02 18:48:21 We do not deoptimize, this is actually the slow-pa
Florian Schneider 2014/09/02 21:03:20 That's why it's in quotes. Intrinsic code uses the
869 ASSERT(!intrinsic_deopt_label_.IsBound());
870 assembler()->Bind(&intrinsic_deopt_label_);
861 } 871 }
862 872
863 873
864 void FlowGraphCompiler::GenerateInstanceCall( 874 void FlowGraphCompiler::GenerateInstanceCall(
865 intptr_t deopt_id, 875 intptr_t deopt_id,
866 intptr_t token_pos, 876 intptr_t token_pos,
867 intptr_t argument_count, 877 intptr_t argument_count,
868 LocationSummary* locs, 878 LocationSummary* locs,
869 const ICData& ic_data) { 879 const ICData& ic_data) {
870 ASSERT(!ic_data.IsNull()); 880 ASSERT(!ic_data.IsNull());
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
1283 return true; 1293 return true;
1284 } 1294 }
1285 } 1295 }
1286 1296
1287 return false; 1297 return false;
1288 } 1298 }
1289 1299
1290 1300
1291 intptr_t ParallelMoveResolver::AllocateScratchRegister( 1301 intptr_t ParallelMoveResolver::AllocateScratchRegister(
1292 Location::Kind kind, 1302 Location::Kind kind,
1293 intptr_t blocked, 1303 uword blocked_mask,
1294 intptr_t first_free_register, 1304 intptr_t first_free_register,
1295 intptr_t last_free_register, 1305 intptr_t last_free_register,
1296 bool* spilled) { 1306 bool* spilled) {
1307 COMPILE_ASSERT(static_cast<intptr_t>(sizeof(blocked_mask)) * kBitsPerByte >=
1308 kNumberOfFpuRegisters);
1309 COMPILE_ASSERT(static_cast<intptr_t>(sizeof(blocked_mask)) * kBitsPerByte >=
1310 kNumberOfCpuRegisters);
1297 intptr_t scratch = -1; 1311 intptr_t scratch = -1;
1298 for (intptr_t reg = first_free_register; reg <= last_free_register; reg++) { 1312 for (intptr_t reg = first_free_register; reg <= last_free_register; reg++) {
1299 if ((blocked != reg) && 1313 if ((((1u << reg) & blocked_mask) == 0) &&
1300 IsScratchLocation(Location::MachineRegisterLocation(kind, reg))) { 1314 IsScratchLocation(Location::MachineRegisterLocation(kind, reg))) {
1301 scratch = reg; 1315 scratch = reg;
1302 break; 1316 break;
1303 } 1317 }
1304 } 1318 }
1305 1319
1306 if (scratch == -1) { 1320 if (scratch == -1) {
1307 *spilled = true; 1321 *spilled = true;
1308 for (intptr_t reg = first_free_register; reg <= last_free_register; reg++) { 1322 for (intptr_t reg = first_free_register; reg <= last_free_register; reg++) {
1309 if (blocked != reg) { 1323 if (((1u << reg) & blocked_mask) == 0) {
1310 scratch = reg; 1324 scratch = reg;
1311 break; 1325 break;
1312 } 1326 }
1313 } 1327 }
1314 } else { 1328 } else {
1315 *spilled = false; 1329 *spilled = false;
1316 } 1330 }
1317 1331
1318 return scratch; 1332 return scratch;
1319 } 1333 }
1320 1334
1321 1335
1322 ParallelMoveResolver::ScratchFpuRegisterScope::ScratchFpuRegisterScope( 1336 ParallelMoveResolver::ScratchFpuRegisterScope::ScratchFpuRegisterScope(
1323 ParallelMoveResolver* resolver, FpuRegister blocked) 1337 ParallelMoveResolver* resolver, FpuRegister blocked)
1324 : resolver_(resolver), 1338 : resolver_(resolver),
1325 reg_(kNoFpuRegister), 1339 reg_(kNoFpuRegister),
1326 spilled_(false) { 1340 spilled_(false) {
1327 reg_ = static_cast<FpuRegister>( 1341 reg_ = static_cast<FpuRegister>(
1328 resolver_->AllocateScratchRegister(Location::kFpuRegister, 1342 resolver_->AllocateScratchRegister(Location::kFpuRegister,
1329 blocked, 1343 1u << blocked,
1330 0, 1344 0,
1331 kNumberOfFpuRegisters - 1, 1345 kNumberOfFpuRegisters - 1,
1332 &spilled_)); 1346 &spilled_));
1333 1347
1334 if (spilled_) { 1348 if (spilled_) {
1335 resolver->SpillFpuScratch(reg_); 1349 resolver->SpillFpuScratch(reg_);
1336 } 1350 }
1337 } 1351 }
1338 1352
1339 1353
1340 ParallelMoveResolver::ScratchFpuRegisterScope::~ScratchFpuRegisterScope() { 1354 ParallelMoveResolver::ScratchFpuRegisterScope::~ScratchFpuRegisterScope() {
1341 if (spilled_) { 1355 if (spilled_) {
1342 resolver_->RestoreFpuScratch(reg_); 1356 resolver_->RestoreFpuScratch(reg_);
1343 } 1357 }
1344 } 1358 }
1345 1359
1346 1360
1347 ParallelMoveResolver::ScratchRegisterScope::ScratchRegisterScope( 1361 ParallelMoveResolver::ScratchRegisterScope::ScratchRegisterScope(
1348 ParallelMoveResolver* resolver, Register blocked) 1362 ParallelMoveResolver* resolver, Register blocked)
1349 : resolver_(resolver), 1363 : resolver_(resolver),
1350 reg_(kNoRegister), 1364 reg_(kNoRegister),
1351 spilled_(false) { 1365 spilled_(false) {
1366 uword blocked_mask = 1u << blocked;
1367 if (resolver->compiler_->intrinsic_mode()) {
1368 // Block additional registers that must be preserved for intrinsics.
1369 blocked_mask |= 1u << ICREG;
1370 blocked_mask |= 1u << ARGS_DESC_REG;
1371 }
1352 reg_ = static_cast<Register>( 1372 reg_ = static_cast<Register>(
1353 resolver_->AllocateScratchRegister(Location::kRegister, 1373 resolver_->AllocateScratchRegister(Location::kRegister,
1354 blocked, 1374 1u << blocked,
1355 kFirstFreeCpuRegister, 1375 kFirstFreeCpuRegister,
1356 kLastFreeCpuRegister, 1376 kLastFreeCpuRegister,
1357 &spilled_)); 1377 &spilled_));
1358 1378
1359 if (spilled_) { 1379 if (spilled_) {
1360 resolver->SpillScratch(reg_); 1380 resolver->SpillScratch(reg_);
1361 } 1381 }
1362 } 1382 }
1363 1383
1364 1384
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1445 threshold = FLAG_optimization_counter_scale * basic_blocks + 1465 threshold = FLAG_optimization_counter_scale * basic_blocks +
1446 FLAG_min_optimization_counter_threshold; 1466 FLAG_min_optimization_counter_threshold;
1447 if (threshold > FLAG_optimization_counter_threshold) { 1467 if (threshold > FLAG_optimization_counter_threshold) {
1448 threshold = FLAG_optimization_counter_threshold; 1468 threshold = FLAG_optimization_counter_threshold;
1449 } 1469 }
1450 } 1470 }
1451 return threshold; 1471 return threshold;
1452 } 1472 }
1453 1473
1454 } // namespace dart 1474 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698