OLD | NEW |
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/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
6 | 6 |
7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
8 #include "vm/dart_entry.h" | 8 #include "vm/dart_entry.h" |
9 #include "vm/flow_graph_allocator.h" | 9 #include "vm/flow_graph_allocator.h" |
10 #include "vm/flow_graph_builder.h" | 10 #include "vm/flow_graph_builder.h" |
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 prev->set_next_use(next); | 502 prev->set_next_use(next); |
503 if (next != NULL) next->set_previous_use(prev); | 503 if (next != NULL) next->set_previous_use(prev); |
504 } | 504 } |
505 | 505 |
506 set_previous_use(NULL); | 506 set_previous_use(NULL); |
507 set_next_use(NULL); | 507 set_next_use(NULL); |
508 } | 508 } |
509 | 509 |
510 | 510 |
511 bool Definition::HasOnlyUse(Value* use) const { | 511 bool Definition::HasOnlyUse(Value* use) const { |
512 if (((input_use_list() == use) && (env_use_list() == NULL)) || | 512 return (input_use_list() == use) && |
513 ((input_use_list() == NULL) && (env_use_list() == use))) { | 513 (use->next_use() == NULL) && |
514 return (use->next_use() == NULL); | 514 ((env_use_list() == NULL) || |
515 } | 515 ((env_use_list()->instruction() == use->instruction()) && |
516 return false; | 516 (env_use_list()->next_use() == NULL))); |
517 } | 517 } |
518 | 518 |
519 | 519 |
520 void Definition::ReplaceUsesWith(Definition* other) { | 520 void Definition::ReplaceUsesWith(Definition* other) { |
521 ASSERT(other != NULL); | 521 ASSERT(other != NULL); |
522 ASSERT(this != other); | 522 ASSERT(this != other); |
523 | 523 |
524 Value* current = NULL; | 524 Value* current = NULL; |
525 Value* next = input_use_list(); | 525 Value* next = input_use_list(); |
526 if (next != NULL) { | 526 if (next != NULL) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
565 void Instruction::UnuseAllInputs() { | 565 void Instruction::UnuseAllInputs() { |
566 for (intptr_t i = InputCount() - 1; i >= 0; --i) { | 566 for (intptr_t i = InputCount() - 1; i >= 0; --i) { |
567 InputAt(i)->RemoveFromUseList(); | 567 InputAt(i)->RemoveFromUseList(); |
568 } | 568 } |
569 for (Environment::DeepIterator it(env()); !it.Done(); it.Advance()) { | 569 for (Environment::DeepIterator it(env()); !it.Done(); it.Advance()) { |
570 it.CurrentValue()->RemoveFromUseList(); | 570 it.CurrentValue()->RemoveFromUseList(); |
571 } | 571 } |
572 } | 572 } |
573 | 573 |
574 | 574 |
| 575 void Instruction::InheritDeoptTargetAfter(Instruction* other) { |
| 576 ASSERT(other->env() != NULL); |
| 577 deopt_id_ = Isolate::ToDeoptAfter(other->deopt_id_); |
| 578 other->env()->DeepCopyTo(this); |
| 579 env()->set_deopt_id(deopt_id_); |
| 580 } |
| 581 |
| 582 |
| 583 void Instruction::InheritDeoptTarget(Instruction* other) { |
| 584 ASSERT(other->env() != NULL); |
| 585 deopt_id_ = other->deopt_id_; |
| 586 other->env()->DeepCopyTo(this); |
| 587 env()->set_deopt_id(deopt_id_); |
| 588 } |
| 589 |
| 590 |
| 591 void BranchInstr::InheritDeoptTarget(Instruction* other) { |
| 592 Instruction::InheritDeoptTarget(other); |
| 593 comparison()->SetDeoptId(GetDeoptId()); |
| 594 } |
| 595 |
| 596 |
575 void Definition::ReplaceWith(Definition* other, | 597 void Definition::ReplaceWith(Definition* other, |
576 ForwardInstructionIterator* iterator) { | 598 ForwardInstructionIterator* iterator) { |
577 // Record other's input uses. | 599 // Record other's input uses. |
578 for (intptr_t i = other->InputCount() - 1; i >= 0; --i) { | 600 for (intptr_t i = other->InputCount() - 1; i >= 0; --i) { |
579 Value* input = other->InputAt(i); | 601 Value* input = other->InputAt(i); |
580 input->definition()->AddInputUse(input); | 602 input->definition()->AddInputUse(input); |
581 } | 603 } |
582 // Take other's environment from this definition. | 604 // Take other's environment from this definition. |
583 ASSERT(other->env() == NULL); | 605 ASSERT(other->env() == NULL); |
584 other->SetEnvironment(env()); | 606 other->SetEnvironment(env()); |
(...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1256 // for conversions. | 1278 // for conversions. |
1257 for (intptr_t i = 0; i < comp->InputCount(); i++) { | 1279 for (intptr_t i = 0; i < comp->InputCount(); i++) { |
1258 if (comp->RequiredInputRepresentation(i) != | 1280 if (comp->RequiredInputRepresentation(i) != |
1259 comp->InputAt(i)->definition()->representation()) { | 1281 comp->InputAt(i)->definition()->representation()) { |
1260 return this; | 1282 return this; |
1261 } | 1283 } |
1262 } | 1284 } |
1263 | 1285 |
1264 // Replace the comparison if the replacement is used at this branch, | 1286 // Replace the comparison if the replacement is used at this branch, |
1265 // and has exactly one use. | 1287 // and has exactly one use. |
1266 if ((comp->input_use_list()->instruction() == this) && | 1288 Value* use = comp->input_use_list(); |
1267 (comp->input_use_list()->next_use() == NULL) && | 1289 if ((use->instruction() == this) && comp->HasOnlyUse(use)) { |
1268 (comp->env_use_list() == NULL)) { | 1290 RemoveEnvironment(); |
| 1291 InheritDeoptTarget(comp); |
| 1292 |
1269 comp->RemoveFromGraph(); | 1293 comp->RemoveFromGraph(); |
1270 SetComparison(comp); | 1294 SetComparison(comp); |
1271 if (FLAG_trace_optimization) { | 1295 if (FLAG_trace_optimization) { |
1272 OS::Print("Merging comparison v%"Pd"\n", comp->ssa_temp_index()); | 1296 OS::Print("Merging comparison v%"Pd"\n", comp->ssa_temp_index()); |
1273 } | 1297 } |
1274 // Clear the comparison's temp index and ssa temp index since the | 1298 // Clear the comparison's temp index and ssa temp index since the |
1275 // value of the comparison is not used outside the branch anymore. | 1299 // value of the comparison is not used outside the branch anymore. |
1276 ASSERT(comp->input_use_list() == NULL); | 1300 ASSERT(comp->input_use_list() == NULL); |
1277 comp->ClearSSATempIndex(); | 1301 comp->ClearSSATempIndex(); |
1278 comp->ClearTempIndex(); | 1302 comp->ClearTempIndex(); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1374 // is located in intermediate_language_<arch>.cc | 1398 // is located in intermediate_language_<arch>.cc |
1375 | 1399 |
1376 #define __ compiler->assembler()-> | 1400 #define __ compiler->assembler()-> |
1377 | 1401 |
1378 void GraphEntryInstr::PrepareEntry(FlowGraphCompiler* compiler) { | 1402 void GraphEntryInstr::PrepareEntry(FlowGraphCompiler* compiler) { |
1379 // Nothing to do. | 1403 // Nothing to do. |
1380 } | 1404 } |
1381 | 1405 |
1382 | 1406 |
1383 void JoinEntryInstr::PrepareEntry(FlowGraphCompiler* compiler) { | 1407 void JoinEntryInstr::PrepareEntry(FlowGraphCompiler* compiler) { |
| 1408 if (!compiler->is_optimizing()) { |
| 1409 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 1410 deopt_id_, |
| 1411 Scanner::kDummyTokenIndex); |
| 1412 } |
1384 __ Bind(compiler->GetJumpLabel(this)); | 1413 __ Bind(compiler->GetJumpLabel(this)); |
1385 if (HasParallelMove()) { | 1414 if (HasParallelMove()) { |
1386 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); | 1415 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); |
1387 } | 1416 } |
1388 } | 1417 } |
1389 | 1418 |
1390 | 1419 |
1391 void TargetEntryInstr::PrepareEntry(FlowGraphCompiler* compiler) { | 1420 void TargetEntryInstr::PrepareEntry(FlowGraphCompiler* compiler) { |
| 1421 if (!compiler->is_optimizing()) { |
| 1422 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 1423 deopt_id_, |
| 1424 Scanner::kDummyTokenIndex); |
| 1425 } |
1392 __ Bind(compiler->GetJumpLabel(this)); | 1426 __ Bind(compiler->GetJumpLabel(this)); |
1393 if (HasParallelMove()) { | 1427 if (HasParallelMove()) { |
1394 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); | 1428 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); |
1395 } | 1429 } |
1396 } | 1430 } |
1397 | 1431 |
1398 | 1432 |
1399 void CatchBlockEntryInstr::PrepareEntry(FlowGraphCompiler* compiler) { | 1433 void CatchBlockEntryInstr::PrepareEntry(FlowGraphCompiler* compiler) { |
1400 __ Bind(compiler->GetJumpLabel(this)); | 1434 __ Bind(compiler->GetJumpLabel(this)); |
1401 compiler->AddExceptionHandler(catch_try_index(), | 1435 compiler->AddExceptionHandler(catch_try_index(), |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1549 compiler->GenerateInstanceCall(deopt_id(), | 1583 compiler->GenerateInstanceCall(deopt_id(), |
1550 token_pos(), | 1584 token_pos(), |
1551 ArgumentCount(), | 1585 ArgumentCount(), |
1552 argument_names(), | 1586 argument_names(), |
1553 locs(), | 1587 locs(), |
1554 call_ic_data); | 1588 call_ic_data); |
1555 } | 1589 } |
1556 } else { | 1590 } else { |
1557 // Unoptimized code. | 1591 // Unoptimized code. |
1558 ASSERT(!HasICData()); | 1592 ASSERT(!HasICData()); |
1559 compiler->AddCurrentDescriptor(PcDescriptors::kDeoptBefore, | 1593 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
1560 deopt_id(), | 1594 deopt_id(), |
1561 token_pos()); | 1595 token_pos()); |
1562 compiler->GenerateInstanceCall(deopt_id(), | 1596 compiler->GenerateInstanceCall(deopt_id(), |
1563 token_pos(), | 1597 token_pos(), |
1564 ArgumentCount(), | 1598 ArgumentCount(), |
1565 argument_names(), | 1599 argument_names(), |
1566 locs(), | 1600 locs(), |
1567 call_ic_data); | 1601 call_ic_data); |
1568 } | 1602 } |
1569 } | 1603 } |
1570 | 1604 |
1571 | 1605 |
1572 LocationSummary* StaticCallInstr::MakeLocationSummary() const { | 1606 LocationSummary* StaticCallInstr::MakeLocationSummary() const { |
1573 return MakeCallSummary(); | 1607 return MakeCallSummary(); |
1574 } | 1608 } |
1575 | 1609 |
1576 | 1610 |
1577 void StaticCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1611 void StaticCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
1578 Label skip_call; | 1612 Label skip_call; |
1579 if (!compiler->is_optimizing()) { | 1613 if (!compiler->is_optimizing()) { |
1580 // Some static calls can be optimized by the optimizing compiler (e.g. sqrt) | 1614 // Some static calls can be optimized by the optimizing compiler (e.g. sqrt) |
1581 // and therefore need a deoptimization descriptor. | 1615 // and therefore need a deoptimization descriptor. |
1582 compiler->AddCurrentDescriptor(PcDescriptors::kDeoptBefore, | 1616 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
1583 deopt_id(), | 1617 deopt_id(), |
1584 token_pos()); | 1618 token_pos()); |
1585 } | 1619 } |
1586 if (function().name() == Symbols::EqualOperator().raw()) { | 1620 if (function().name() == Symbols::EqualOperator().raw()) { |
1587 compiler->EmitSuperEqualityCallPrologue(locs()->out().reg(), &skip_call); | 1621 compiler->EmitSuperEqualityCallPrologue(locs()->out().reg(), &skip_call); |
1588 } | 1622 } |
1589 compiler->GenerateStaticCall(deopt_id(), | 1623 compiler->GenerateStaticCall(deopt_id(), |
1590 token_pos(), | 1624 token_pos(), |
1591 function(), | 1625 function(), |
1592 ArgumentCount(), | 1626 ArgumentCount(), |
(...skipping 747 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2340 default: | 2374 default: |
2341 UNREACHABLE(); | 2375 UNREACHABLE(); |
2342 } | 2376 } |
2343 return kPowRuntimeEntry; | 2377 return kPowRuntimeEntry; |
2344 } | 2378 } |
2345 | 2379 |
2346 | 2380 |
2347 #undef __ | 2381 #undef __ |
2348 | 2382 |
2349 } // namespace dart | 2383 } // namespace dart |
OLD | NEW |