| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/pipeline.h" | 5 #include "src/compiler/pipeline.h" |
| 6 | 6 |
| 7 #include <fstream> // NOLINT(readability/streams) | 7 #include <fstream> // NOLINT(readability/streams) |
| 8 #include <sstream> | 8 #include <sstream> |
| 9 | 9 |
| 10 #include "src/base/adapters.h" | 10 #include "src/base/adapters.h" |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 } | 280 } |
| 281 | 281 |
| 282 void InitializeRegisterAllocationData(const RegisterConfiguration* config, | 282 void InitializeRegisterAllocationData(const RegisterConfiguration* config, |
| 283 CallDescriptor* descriptor) { | 283 CallDescriptor* descriptor) { |
| 284 DCHECK(register_allocation_data_ == nullptr); | 284 DCHECK(register_allocation_data_ == nullptr); |
| 285 register_allocation_data_ = new (register_allocation_zone()) | 285 register_allocation_data_ = new (register_allocation_zone()) |
| 286 RegisterAllocationData(config, register_allocation_zone(), frame(), | 286 RegisterAllocationData(config, register_allocation_zone(), frame(), |
| 287 sequence(), debug_name_.get()); | 287 sequence(), debug_name_.get()); |
| 288 } | 288 } |
| 289 | 289 |
| 290 void BeginPhaseKind(const char* phase_kind_name) { |
| 291 if (pipeline_statistics() != nullptr) { |
| 292 pipeline_statistics()->BeginPhaseKind(phase_kind_name); |
| 293 } |
| 294 } |
| 295 |
| 296 void EndPhaseKind() { |
| 297 if (pipeline_statistics() != nullptr) { |
| 298 pipeline_statistics()->EndPhaseKind(); |
| 299 } |
| 300 } |
| 301 |
| 290 private: | 302 private: |
| 291 Isolate* const isolate_; | 303 Isolate* const isolate_; |
| 292 CompilationInfo* const info_; | 304 CompilationInfo* const info_; |
| 293 base::SmartArrayPointer<char> debug_name_; | 305 base::SmartArrayPointer<char> debug_name_; |
| 294 Zone* outer_zone_ = nullptr; | 306 Zone* outer_zone_ = nullptr; |
| 295 ZonePool* const zone_pool_; | 307 ZonePool* const zone_pool_; |
| 296 PipelineStatistics* pipeline_statistics_ = nullptr; | 308 PipelineStatistics* pipeline_statistics_ = nullptr; |
| 297 bool compilation_failed_ = false; | 309 bool compilation_failed_ = false; |
| 298 Handle<Code> code_ = Handle<Code>::null(); | 310 Handle<Code> code_ = Handle<Code>::null(); |
| 299 | 311 |
| (...skipping 977 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1277 static const char* phase_name() { return nullptr; } | 1289 static const char* phase_name() { return nullptr; } |
| 1278 | 1290 |
| 1279 void Run(PipelineData* data, Zone* temp_zone, const bool untyped, | 1291 void Run(PipelineData* data, Zone* temp_zone, const bool untyped, |
| 1280 bool values_only = false) { | 1292 bool values_only = false) { |
| 1281 Verifier::Run(data->graph(), !untyped ? Verifier::TYPED : Verifier::UNTYPED, | 1293 Verifier::Run(data->graph(), !untyped ? Verifier::TYPED : Verifier::UNTYPED, |
| 1282 values_only ? Verifier::kValuesOnly : Verifier::kAll); | 1294 values_only ? Verifier::kValuesOnly : Verifier::kAll); |
| 1283 } | 1295 } |
| 1284 }; | 1296 }; |
| 1285 | 1297 |
| 1286 | 1298 |
| 1287 void Pipeline::BeginPhaseKind(const char* phase_kind_name) { | |
| 1288 if (data_->pipeline_statistics() != nullptr) { | |
| 1289 data_->pipeline_statistics()->BeginPhaseKind(phase_kind_name); | |
| 1290 } | |
| 1291 } | |
| 1292 | |
| 1293 void Pipeline::EndPhaseKind() { | |
| 1294 if (data_->pipeline_statistics() != nullptr) { | |
| 1295 data_->pipeline_statistics()->EndPhaseKind(); | |
| 1296 } | |
| 1297 } | |
| 1298 | |
| 1299 void Pipeline::RunPrintAndVerify(const char* phase, bool untyped) { | 1299 void Pipeline::RunPrintAndVerify(const char* phase, bool untyped) { |
| 1300 if (FLAG_trace_turbo) { | 1300 if (FLAG_trace_turbo) { |
| 1301 Run<PrintGraphPhase>(phase); | 1301 Run<PrintGraphPhase>(phase); |
| 1302 } | 1302 } |
| 1303 if (FLAG_turbo_verify) { | 1303 if (FLAG_turbo_verify) { |
| 1304 Run<VerifyGraphPhase>(untyped); | 1304 Run<VerifyGraphPhase>(untyped); |
| 1305 } | 1305 } |
| 1306 } | 1306 } |
| 1307 | 1307 |
| 1308 bool Pipeline::CreateGraph() { | 1308 bool Pipeline::CreateGraph() { |
| 1309 PipelineData* data = this->data_; | 1309 PipelineData* data = this->data_; |
| 1310 | 1310 |
| 1311 BeginPhaseKind("graph creation"); | 1311 data->BeginPhaseKind("graph creation"); |
| 1312 | 1312 |
| 1313 if (FLAG_trace_turbo) { | 1313 if (FLAG_trace_turbo) { |
| 1314 OFStream os(stdout); | 1314 OFStream os(stdout); |
| 1315 os << "---------------------------------------------------\n" | 1315 os << "---------------------------------------------------\n" |
| 1316 << "Begin compiling method " << info()->GetDebugName().get() | 1316 << "Begin compiling method " << info()->GetDebugName().get() |
| 1317 << " using Turbofan" << std::endl; | 1317 << " using Turbofan" << std::endl; |
| 1318 TurboCfgFile tcf(isolate()); | 1318 TurboCfgFile tcf(isolate()); |
| 1319 tcf << AsC1VCompilation(info()); | 1319 tcf << AsC1VCompilation(info()); |
| 1320 } | 1320 } |
| 1321 | 1321 |
| 1322 data->source_positions()->AddDecorator(); | 1322 data->source_positions()->AddDecorator(); |
| 1323 | 1323 |
| 1324 if (FLAG_loop_assignment_analysis) { | 1324 if (FLAG_loop_assignment_analysis) { |
| 1325 Run<LoopAssignmentAnalysisPhase>(); | 1325 Run<LoopAssignmentAnalysisPhase>(); |
| 1326 } | 1326 } |
| 1327 | 1327 |
| 1328 Run<TypeHintAnalysisPhase>(); | 1328 Run<TypeHintAnalysisPhase>(); |
| 1329 | 1329 |
| 1330 Run<GraphBuilderPhase>(); | 1330 Run<GraphBuilderPhase>(); |
| 1331 if (data->compilation_failed()) { | 1331 if (data->compilation_failed()) { |
| 1332 EndPhaseKind(); | 1332 data->EndPhaseKind(); |
| 1333 return false; | 1333 return false; |
| 1334 } | 1334 } |
| 1335 RunPrintAndVerify("Initial untyped", true); | 1335 RunPrintAndVerify("Initial untyped", true); |
| 1336 | 1336 |
| 1337 // Perform OSR deconstruction. | 1337 // Perform OSR deconstruction. |
| 1338 if (info()->is_osr()) { | 1338 if (info()->is_osr()) { |
| 1339 Run<OsrDeconstructionPhase>(); | 1339 Run<OsrDeconstructionPhase>(); |
| 1340 RunPrintAndVerify("OSR deconstruction", true); | 1340 RunPrintAndVerify("OSR deconstruction", true); |
| 1341 } | 1341 } |
| 1342 | 1342 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1358 // Type the graph and keep the Typer running on newly created nodes within | 1358 // Type the graph and keep the Typer running on newly created nodes within |
| 1359 // this scope; the Typer is automatically unlinked from the Graph once we | 1359 // this scope; the Typer is automatically unlinked from the Graph once we |
| 1360 // leave this scope below. | 1360 // leave this scope below. |
| 1361 Typer typer(isolate(), data->graph(), info()->is_deoptimization_enabled() | 1361 Typer typer(isolate(), data->graph(), info()->is_deoptimization_enabled() |
| 1362 ? Typer::kDeoptimizationEnabled | 1362 ? Typer::kDeoptimizationEnabled |
| 1363 : Typer::kNoFlags, | 1363 : Typer::kNoFlags, |
| 1364 info()->dependencies()); | 1364 info()->dependencies()); |
| 1365 Run<TyperPhase>(&typer); | 1365 Run<TyperPhase>(&typer); |
| 1366 RunPrintAndVerify("Typed"); | 1366 RunPrintAndVerify("Typed"); |
| 1367 | 1367 |
| 1368 BeginPhaseKind("lowering"); | 1368 data->BeginPhaseKind("lowering"); |
| 1369 | 1369 |
| 1370 // Lower JSOperators where we can determine types. | 1370 // Lower JSOperators where we can determine types. |
| 1371 Run<TypedLoweringPhase>(); | 1371 Run<TypedLoweringPhase>(); |
| 1372 RunPrintAndVerify("Lowered typed"); | 1372 RunPrintAndVerify("Lowered typed"); |
| 1373 | 1373 |
| 1374 if (FLAG_turbo_stress_loop_peeling) { | 1374 if (FLAG_turbo_stress_loop_peeling) { |
| 1375 Run<StressLoopPeelingPhase>(); | 1375 Run<StressLoopPeelingPhase>(); |
| 1376 RunPrintAndVerify("Loop peeled"); | 1376 RunPrintAndVerify("Loop peeled"); |
| 1377 } | 1377 } |
| 1378 | 1378 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1400 // selection due to the way we handle truncations; if we'd want to look | 1400 // selection due to the way we handle truncations; if we'd want to look |
| 1401 // at types afterwards we'd essentially need to re-type (large portions | 1401 // at types afterwards we'd essentially need to re-type (large portions |
| 1402 // of) the graph. | 1402 // of) the graph. |
| 1403 // | 1403 // |
| 1404 // In order to catch bugs related to type access after this point we remove | 1404 // In order to catch bugs related to type access after this point we remove |
| 1405 // the types from the nodes at this point (currently only in Debug builds). | 1405 // the types from the nodes at this point (currently only in Debug builds). |
| 1406 Run<UntyperPhase>(); | 1406 Run<UntyperPhase>(); |
| 1407 RunPrintAndVerify("Untyped", true); | 1407 RunPrintAndVerify("Untyped", true); |
| 1408 #endif | 1408 #endif |
| 1409 | 1409 |
| 1410 EndPhaseKind(); | 1410 data->EndPhaseKind(); |
| 1411 | 1411 |
| 1412 return true; | 1412 return true; |
| 1413 } | 1413 } |
| 1414 | 1414 |
| 1415 bool Pipeline::OptimizeGraph(Linkage* linkage) { | 1415 bool Pipeline::OptimizeGraph(Linkage* linkage) { |
| 1416 PipelineData* data = this->data_; | 1416 PipelineData* data = this->data_; |
| 1417 | 1417 |
| 1418 BeginPhaseKind("block building"); | 1418 data->BeginPhaseKind("block building"); |
| 1419 | 1419 |
| 1420 Run<EffectControlLinearizationPhase>(); | 1420 Run<EffectControlLinearizationPhase>(); |
| 1421 RunPrintAndVerify("Effect and control linearized", true); | 1421 RunPrintAndVerify("Effect and control linearized", true); |
| 1422 | 1422 |
| 1423 Run<BranchEliminationPhase>(); | 1423 Run<BranchEliminationPhase>(); |
| 1424 RunPrintAndVerify("Branch conditions eliminated", true); | 1424 RunPrintAndVerify("Branch conditions eliminated", true); |
| 1425 | 1425 |
| 1426 // Optimize control flow. | 1426 // Optimize control flow. |
| 1427 if (FLAG_turbo_cf_optimization) { | 1427 if (FLAG_turbo_cf_optimization) { |
| 1428 Run<ControlFlowOptimizationPhase>(); | 1428 Run<ControlFlowOptimizationPhase>(); |
| 1429 RunPrintAndVerify("Control flow optimized", true); | 1429 RunPrintAndVerify("Control flow optimized", true); |
| 1430 } | 1430 } |
| 1431 | 1431 |
| 1432 // Lower changes that have been inserted before. | 1432 // Lower changes that have been inserted before. |
| 1433 Run<LateOptimizationPhase>(); | 1433 Run<LateOptimizationPhase>(); |
| 1434 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. | 1434 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. |
| 1435 RunPrintAndVerify("Late optimized", true); | 1435 RunPrintAndVerify("Late optimized", true); |
| 1436 | 1436 |
| 1437 Run<LateGraphTrimmingPhase>(); | 1437 Run<LateGraphTrimmingPhase>(); |
| 1438 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. | 1438 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. |
| 1439 RunPrintAndVerify("Late trimmed", true); | 1439 RunPrintAndVerify("Late trimmed", true); |
| 1440 | 1440 |
| 1441 data->source_positions()->RemoveDecorator(); | 1441 data->source_positions()->RemoveDecorator(); |
| 1442 | 1442 |
| 1443 return ScheduleAndSelectInstructions(linkage); | 1443 return ScheduleAndSelectInstructions(linkage); |
| 1444 } | 1444 } |
| 1445 | 1445 |
| 1446 Handle<Code> Pipeline::GenerateCode() { | |
| 1447 PipelineData* data = this->data_; | |
| 1448 | |
| 1449 Linkage linkage(Linkage::ComputeIncoming(data->instruction_zone(), info())); | |
| 1450 | |
| 1451 if (!CreateGraph()) return Handle<Code>::null(); | |
| 1452 if (!OptimizeGraph(&linkage)) return Handle<Code>::null(); | |
| 1453 return GenerateCode(&linkage); | |
| 1454 } | |
| 1455 | |
| 1456 Handle<Code> Pipeline::GenerateCodeForCodeStub(Isolate* isolate, | 1446 Handle<Code> Pipeline::GenerateCodeForCodeStub(Isolate* isolate, |
| 1457 CallDescriptor* call_descriptor, | 1447 CallDescriptor* call_descriptor, |
| 1458 Graph* graph, Schedule* schedule, | 1448 Graph* graph, Schedule* schedule, |
| 1459 Code::Flags flags, | 1449 Code::Flags flags, |
| 1460 const char* debug_name) { | 1450 const char* debug_name) { |
| 1461 CompilationInfo info(CStrVector(debug_name), isolate, graph->zone(), flags); | 1451 CompilationInfo info(CStrVector(debug_name), isolate, graph->zone(), flags); |
| 1462 | 1452 |
| 1463 // Construct a pipeline for scheduling and code generation. | 1453 // Construct a pipeline for scheduling and code generation. |
| 1464 ZonePool zone_pool(isolate->allocator()); | 1454 ZonePool zone_pool(isolate->allocator()); |
| 1465 PipelineData data(&zone_pool, &info, graph, schedule); | 1455 PipelineData data(&zone_pool, &info, graph, schedule); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1487 return pipeline.ScheduleAndGenerateCode(call_descriptor); | 1477 return pipeline.ScheduleAndGenerateCode(call_descriptor); |
| 1488 } | 1478 } |
| 1489 | 1479 |
| 1490 // static | 1480 // static |
| 1491 Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info) { | 1481 Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info) { |
| 1492 ZonePool zone_pool(info->isolate()->allocator()); | 1482 ZonePool zone_pool(info->isolate()->allocator()); |
| 1493 base::SmartPointer<PipelineStatistics> pipeline_statistics( | 1483 base::SmartPointer<PipelineStatistics> pipeline_statistics( |
| 1494 CreatePipelineStatistics(info, &zone_pool)); | 1484 CreatePipelineStatistics(info, &zone_pool)); |
| 1495 PipelineData data(&zone_pool, info, pipeline_statistics.get()); | 1485 PipelineData data(&zone_pool, info, pipeline_statistics.get()); |
| 1496 Pipeline pipeline(&data); | 1486 Pipeline pipeline(&data); |
| 1497 return pipeline.GenerateCode(); | 1487 |
| 1488 Linkage linkage(Linkage::ComputeIncoming(data.instruction_zone(), info)); |
| 1489 |
| 1490 if (!pipeline.CreateGraph()) return Handle<Code>::null(); |
| 1491 if (!pipeline.OptimizeGraph(&linkage)) return Handle<Code>::null(); |
| 1492 return pipeline.GenerateCode(&linkage); |
| 1498 } | 1493 } |
| 1499 | 1494 |
| 1500 // static | 1495 // static |
| 1501 Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info, | 1496 Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info, |
| 1502 Graph* graph, | 1497 Graph* graph, |
| 1503 Schedule* schedule) { | 1498 Schedule* schedule) { |
| 1504 CallDescriptor* call_descriptor = | 1499 CallDescriptor* call_descriptor = |
| 1505 Linkage::ComputeIncoming(info->zone(), info); | 1500 Linkage::ComputeIncoming(info->zone(), info); |
| 1506 return GenerateCodeForTesting(info, call_descriptor, graph, schedule); | 1501 return GenerateCodeForTesting(info, call_descriptor, graph, schedule); |
| 1507 } | 1502 } |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1591 | 1586 |
| 1592 if (FLAG_trace_turbo) { | 1587 if (FLAG_trace_turbo) { |
| 1593 std::ostringstream source_position_output; | 1588 std::ostringstream source_position_output; |
| 1594 // Output source position information before the graph is deleted. | 1589 // Output source position information before the graph is deleted. |
| 1595 data_->source_positions()->Print(source_position_output); | 1590 data_->source_positions()->Print(source_position_output); |
| 1596 data_->set_source_position_output(source_position_output.str()); | 1591 data_->set_source_position_output(source_position_output.str()); |
| 1597 } | 1592 } |
| 1598 | 1593 |
| 1599 data->DeleteGraphZone(); | 1594 data->DeleteGraphZone(); |
| 1600 | 1595 |
| 1601 BeginPhaseKind("register allocation"); | 1596 data->BeginPhaseKind("register allocation"); |
| 1602 | 1597 |
| 1603 bool run_verifier = FLAG_turbo_verify_allocation; | 1598 bool run_verifier = FLAG_turbo_verify_allocation; |
| 1604 | 1599 |
| 1605 // Allocate registers. | 1600 // Allocate registers. |
| 1606 AllocateRegisters( | 1601 AllocateRegisters( |
| 1607 RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN), | 1602 RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN), |
| 1608 call_descriptor, run_verifier); | 1603 call_descriptor, run_verifier); |
| 1609 Run<FrameElisionPhase>(); | 1604 Run<FrameElisionPhase>(); |
| 1610 if (data->compilation_failed()) { | 1605 if (data->compilation_failed()) { |
| 1611 info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc); | 1606 info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc); |
| 1612 EndPhaseKind(); | 1607 data->EndPhaseKind(); |
| 1613 return false; | 1608 return false; |
| 1614 } | 1609 } |
| 1615 | 1610 |
| 1616 // TODO(mtrofin): move this off to the register allocator. | 1611 // TODO(mtrofin): move this off to the register allocator. |
| 1617 bool generate_frame_at_start = | 1612 bool generate_frame_at_start = |
| 1618 data_->sequence()->instruction_blocks().front()->must_construct_frame(); | 1613 data_->sequence()->instruction_blocks().front()->must_construct_frame(); |
| 1619 // Optimimize jumps. | 1614 // Optimimize jumps. |
| 1620 if (FLAG_turbo_jt) { | 1615 if (FLAG_turbo_jt) { |
| 1621 Run<JumpThreadingPhase>(generate_frame_at_start); | 1616 Run<JumpThreadingPhase>(generate_frame_at_start); |
| 1622 } | 1617 } |
| 1623 | 1618 |
| 1624 EndPhaseKind(); | 1619 data->EndPhaseKind(); |
| 1625 | 1620 |
| 1626 return true; | 1621 return true; |
| 1627 } | 1622 } |
| 1628 | 1623 |
| 1629 Handle<Code> Pipeline::GenerateCode(Linkage* linkage) { | 1624 Handle<Code> Pipeline::GenerateCode(Linkage* linkage) { |
| 1630 PipelineData* data = this->data_; | 1625 PipelineData* data = this->data_; |
| 1631 | 1626 |
| 1632 BeginPhaseKind("code generation"); | 1627 data->BeginPhaseKind("code generation"); |
| 1633 | 1628 |
| 1634 // Generate final machine code. | 1629 // Generate final machine code. |
| 1635 Run<GenerateCodePhase>(linkage); | 1630 Run<GenerateCodePhase>(linkage); |
| 1636 | 1631 |
| 1637 Handle<Code> code = data->code(); | 1632 Handle<Code> code = data->code(); |
| 1638 if (data->profiler_data()) { | 1633 if (data->profiler_data()) { |
| 1639 #if ENABLE_DISASSEMBLER | 1634 #if ENABLE_DISASSEMBLER |
| 1640 std::ostringstream os; | 1635 std::ostringstream os; |
| 1641 code->Disassemble(nullptr, os); | 1636 code->Disassemble(nullptr, os); |
| 1642 data->profiler_data()->SetCode(&os); | 1637 data->profiler_data()->SetCode(&os); |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1775 data->DeleteRegisterAllocationZone(); | 1770 data->DeleteRegisterAllocationZone(); |
| 1776 } | 1771 } |
| 1777 | 1772 |
| 1778 CompilationInfo* Pipeline::info() const { return data_->info(); } | 1773 CompilationInfo* Pipeline::info() const { return data_->info(); } |
| 1779 | 1774 |
| 1780 Isolate* Pipeline::isolate() const { return info()->isolate(); } | 1775 Isolate* Pipeline::isolate() const { return info()->isolate(); } |
| 1781 | 1776 |
| 1782 } // namespace compiler | 1777 } // namespace compiler |
| 1783 } // namespace internal | 1778 } // namespace internal |
| 1784 } // namespace v8 | 1779 } // namespace v8 |
| OLD | NEW |