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" |
11 #include "src/base/platform/elapsed-timer.h" | 11 #include "src/base/platform/elapsed-timer.h" |
12 #include "src/compiler/ast-graph-builder.h" | 12 #include "src/compiler/ast-graph-builder.h" |
13 #include "src/compiler/ast-loop-assignment-analyzer.h" | 13 #include "src/compiler/ast-loop-assignment-analyzer.h" |
14 #include "src/compiler/basic-block-instrumentor.h" | 14 #include "src/compiler/basic-block-instrumentor.h" |
15 #include "src/compiler/branch-elimination.h" | 15 #include "src/compiler/branch-elimination.h" |
16 #include "src/compiler/bytecode-graph-builder.h" | 16 #include "src/compiler/bytecode-graph-builder.h" |
17 #include "src/compiler/change-lowering.h" | 17 #include "src/compiler/change-lowering.h" |
18 #include "src/compiler/code-generator.h" | 18 #include "src/compiler/code-generator.h" |
19 #include "src/compiler/common-operator-reducer.h" | 19 #include "src/compiler/common-operator-reducer.h" |
20 #include "src/compiler/control-flow-optimizer.h" | 20 #include "src/compiler/control-flow-optimizer.h" |
21 #include "src/compiler/dead-code-elimination.h" | 21 #include "src/compiler/dead-code-elimination.h" |
| 22 #include "src/compiler/effect-control-linearizer.h" |
22 #include "src/compiler/escape-analysis-reducer.h" | 23 #include "src/compiler/escape-analysis-reducer.h" |
23 #include "src/compiler/escape-analysis.h" | 24 #include "src/compiler/escape-analysis.h" |
24 #include "src/compiler/frame-elider.h" | 25 #include "src/compiler/frame-elider.h" |
25 #include "src/compiler/graph-replay.h" | 26 #include "src/compiler/graph-replay.h" |
26 #include "src/compiler/graph-trimmer.h" | 27 #include "src/compiler/graph-trimmer.h" |
27 #include "src/compiler/graph-visualizer.h" | 28 #include "src/compiler/graph-visualizer.h" |
28 #include "src/compiler/greedy-allocator.h" | 29 #include "src/compiler/greedy-allocator.h" |
29 #include "src/compiler/instruction-selector.h" | 30 #include "src/compiler/instruction-selector.h" |
30 #include "src/compiler/instruction.h" | 31 #include "src/compiler/instruction.h" |
31 #include "src/compiler/js-builtin-reducer.h" | 32 #include "src/compiler/js-builtin-reducer.h" |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 void set_type_hint_analysis(TypeHintAnalysis* type_hint_analysis) { | 219 void set_type_hint_analysis(TypeHintAnalysis* type_hint_analysis) { |
219 DCHECK_NULL(type_hint_analysis_); | 220 DCHECK_NULL(type_hint_analysis_); |
220 type_hint_analysis_ = type_hint_analysis; | 221 type_hint_analysis_ = type_hint_analysis; |
221 } | 222 } |
222 | 223 |
223 Schedule* schedule() const { return schedule_; } | 224 Schedule* schedule() const { return schedule_; } |
224 void set_schedule(Schedule* schedule) { | 225 void set_schedule(Schedule* schedule) { |
225 DCHECK(!schedule_); | 226 DCHECK(!schedule_); |
226 schedule_ = schedule; | 227 schedule_ = schedule; |
227 } | 228 } |
| 229 void reset_schedule() { schedule_ = nullptr; } |
228 | 230 |
229 Zone* instruction_zone() const { return instruction_zone_; } | 231 Zone* instruction_zone() const { return instruction_zone_; } |
230 InstructionSequence* sequence() const { return sequence_; } | 232 InstructionSequence* sequence() const { return sequence_; } |
231 Frame* frame() const { return frame_; } | 233 Frame* frame() const { return frame_; } |
232 | 234 |
233 Zone* register_allocation_zone() const { return register_allocation_zone_; } | 235 Zone* register_allocation_zone() const { return register_allocation_zone_; } |
234 RegisterAllocationData* register_allocation_data() const { | 236 RegisterAllocationData* register_allocation_data() const { |
235 return register_allocation_data_; | 237 return register_allocation_data_; |
236 } | 238 } |
237 | 239 |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
496 if (!FLAG_always_opt) { | 498 if (!FLAG_always_opt) { |
497 info()->MarkAsBailoutOnUninitialized(); | 499 info()->MarkAsBailoutOnUninitialized(); |
498 } | 500 } |
499 if (FLAG_native_context_specialization) { | 501 if (FLAG_native_context_specialization) { |
500 info()->MarkAsNativeContextSpecializing(); | 502 info()->MarkAsNativeContextSpecializing(); |
501 } | 503 } |
502 } | 504 } |
503 if (!info()->shared_info()->asm_function() || FLAG_turbo_asm_deoptimization) { | 505 if (!info()->shared_info()->asm_function() || FLAG_turbo_asm_deoptimization) { |
504 info()->MarkAsDeoptimizationEnabled(); | 506 info()->MarkAsDeoptimizationEnabled(); |
505 } | 507 } |
| 508 if (!info()->shared_info()->asm_function()) { |
| 509 info()->MarkAsEffectSchedulingEnabled(); |
| 510 } |
506 | 511 |
507 if (!info()->shared_info()->HasBytecodeArray()) { | 512 if (!info()->shared_info()->HasBytecodeArray()) { |
508 if (!Compiler::EnsureDeoptimizationSupport(info())) return FAILED; | 513 if (!Compiler::EnsureDeoptimizationSupport(info())) return FAILED; |
509 } | 514 } |
510 | 515 |
511 Pipeline pipeline(info()); | 516 Pipeline pipeline(info()); |
512 pipeline.GenerateCode(); | 517 pipeline.GenerateCode(); |
513 if (isolate()->has_pending_exception()) return FAILED; // Stack overflowed. | 518 if (isolate()->has_pending_exception()) return FAILED; // Stack overflowed. |
514 if (info()->code().is_null()) return AbortOptimization(kGraphBuildingFailed); | 519 if (info()->code().is_null()) return AbortOptimization(kGraphBuildingFailed); |
515 | 520 |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
792 struct ControlFlowOptimizationPhase { | 797 struct ControlFlowOptimizationPhase { |
793 static const char* phase_name() { return "control flow optimization"; } | 798 static const char* phase_name() { return "control flow optimization"; } |
794 | 799 |
795 void Run(PipelineData* data, Zone* temp_zone) { | 800 void Run(PipelineData* data, Zone* temp_zone) { |
796 ControlFlowOptimizer optimizer(data->graph(), data->common(), | 801 ControlFlowOptimizer optimizer(data->graph(), data->common(), |
797 data->machine(), temp_zone); | 802 data->machine(), temp_zone); |
798 optimizer.Optimize(); | 803 optimizer.Optimize(); |
799 } | 804 } |
800 }; | 805 }; |
801 | 806 |
| 807 struct EffectControlLinearizationPhase { |
| 808 static const char* phase_name() { return "effect linearization"; } |
| 809 |
| 810 void Run(PipelineData* data, Zone* temp_zone) { |
| 811 // The scheduler requires the graphs to be trimmed, so trim now. |
| 812 // TODO(jarin) Remove the trimming once the scheduler can handle untrimmed |
| 813 // graphs. |
| 814 GraphTrimmer trimmer(temp_zone, data->graph()); |
| 815 NodeVector roots(temp_zone); |
| 816 data->jsgraph()->GetCachedNodes(&roots); |
| 817 trimmer.TrimGraph(roots.begin(), roots.end()); |
| 818 |
| 819 // Schedule the graph without node splitting so that we can |
| 820 // fix the effect and control flow for nodes with low-level side |
| 821 // effects (such as changing representation to tagged or |
| 822 // 'floating' allocation regions.) |
| 823 Schedule* schedule = Scheduler::ComputeSchedule(temp_zone, data->graph(), |
| 824 Scheduler::kNoFlags); |
| 825 if (FLAG_turbo_verify) ScheduleVerifier::Run(schedule); |
| 826 |
| 827 // Post-pass for wiring the control/effects |
| 828 // - connect allocating representation changes into the control&effect |
| 829 // chains and lower them, |
| 830 // - get rid of the region markers, |
| 831 // - introduce effect phis and rewire effects to get SSA again. |
| 832 EffectControlLinearizer introducer(data->jsgraph(), schedule, temp_zone); |
| 833 introducer.Run(); |
| 834 } |
| 835 }; |
802 | 836 |
803 struct ChangeLoweringPhase { | 837 struct ChangeLoweringPhase { |
804 static const char* phase_name() { return "change lowering"; } | 838 static const char* phase_name() { return "change lowering"; } |
805 | 839 |
806 void Run(PipelineData* data, Zone* temp_zone) { | 840 void Run(PipelineData* data, Zone* temp_zone) { |
807 JSGraphReducer graph_reducer(data->jsgraph(), temp_zone); | 841 JSGraphReducer graph_reducer(data->jsgraph(), temp_zone); |
808 DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(), | 842 DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(), |
809 data->common()); | 843 data->common()); |
810 SimplifiedOperatorReducer simple_reducer(data->jsgraph()); | 844 SimplifiedOperatorReducer simple_reducer(data->jsgraph()); |
811 ValueNumberingReducer value_numbering(temp_zone); | 845 ValueNumberingReducer value_numbering(temp_zone); |
812 ChangeLowering lowering(data->jsgraph()); | 846 ChangeLowering lowering(data->jsgraph()); |
813 MachineOperatorReducer machine_reducer(data->jsgraph()); | 847 MachineOperatorReducer machine_reducer(data->jsgraph()); |
814 CommonOperatorReducer common_reducer(&graph_reducer, data->graph(), | 848 CommonOperatorReducer common_reducer(&graph_reducer, data->graph(), |
815 data->common(), data->machine()); | 849 data->common(), data->machine()); |
816 AddReducer(data, &graph_reducer, &dead_code_elimination); | 850 AddReducer(data, &graph_reducer, &dead_code_elimination); |
817 AddReducer(data, &graph_reducer, &simple_reducer); | 851 AddReducer(data, &graph_reducer, &simple_reducer); |
818 AddReducer(data, &graph_reducer, &value_numbering); | 852 AddReducer(data, &graph_reducer, &value_numbering); |
819 AddReducer(data, &graph_reducer, &lowering); | 853 AddReducer(data, &graph_reducer, &lowering); |
820 AddReducer(data, &graph_reducer, &machine_reducer); | 854 AddReducer(data, &graph_reducer, &machine_reducer); |
821 AddReducer(data, &graph_reducer, &common_reducer); | 855 AddReducer(data, &graph_reducer, &common_reducer); |
822 graph_reducer.ReduceGraph(); | 856 graph_reducer.ReduceGraph(); |
823 } | 857 } |
824 }; | 858 }; |
825 | 859 |
| 860 struct ComputeEffectSchedulePhase { |
| 861 static const char* phase_name() { return "effect scheduling"; } |
| 862 |
| 863 void Run(PipelineData* data, Zone* temp_zone) { |
| 864 Schedule* schedule = Scheduler::ComputeSchedule(temp_zone, data->graph(), |
| 865 Scheduler::kNoFlags); |
| 866 if (FLAG_turbo_verify) ScheduleVerifier::Run(schedule); |
| 867 data->set_schedule(schedule); |
| 868 } |
| 869 }; |
| 870 |
| 871 struct EffectScheduleTrimmingPhase { |
| 872 static const char* phase_name() { return "effect schedule graph trimming"; } |
| 873 void Run(PipelineData* data, Zone* temp_zone) { |
| 874 GraphTrimmer trimmer(temp_zone, data->graph()); |
| 875 NodeVector roots(temp_zone); |
| 876 data->jsgraph()->GetCachedNodes(&roots); |
| 877 trimmer.TrimGraph(roots.begin(), roots.end()); |
| 878 } |
| 879 }; |
826 | 880 |
827 struct EarlyGraphTrimmingPhase { | 881 struct EarlyGraphTrimmingPhase { |
828 static const char* phase_name() { return "early graph trimming"; } | 882 static const char* phase_name() { return "early graph trimming"; } |
829 void Run(PipelineData* data, Zone* temp_zone) { | 883 void Run(PipelineData* data, Zone* temp_zone) { |
830 GraphTrimmer trimmer(temp_zone, data->graph()); | 884 GraphTrimmer trimmer(temp_zone, data->graph()); |
831 NodeVector roots(temp_zone); | 885 NodeVector roots(temp_zone); |
832 data->jsgraph()->GetCachedNodes(&roots); | 886 data->jsgraph()->GetCachedNodes(&roots); |
833 trimmer.TrimGraph(roots.begin(), roots.end()); | 887 trimmer.TrimGraph(roots.begin(), roots.end()); |
834 } | 888 } |
835 }; | 889 }; |
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1244 | 1298 |
1245 if (FLAG_turbo_escape) { | 1299 if (FLAG_turbo_escape) { |
1246 Run<EscapeAnalysisPhase>(); | 1300 Run<EscapeAnalysisPhase>(); |
1247 RunPrintAndVerify("Escape Analysed"); | 1301 RunPrintAndVerify("Escape Analysed"); |
1248 } | 1302 } |
1249 | 1303 |
1250 // Lower simplified operators and insert changes. | 1304 // Lower simplified operators and insert changes. |
1251 Run<SimplifiedLoweringPhase>(); | 1305 Run<SimplifiedLoweringPhase>(); |
1252 RunPrintAndVerify("Lowered simplified"); | 1306 RunPrintAndVerify("Lowered simplified"); |
1253 | 1307 |
| 1308 if (info()->is_effect_scheduling_enabled()) { |
| 1309 // TODO(jarin) Run value numbering for the representation changes. |
| 1310 Run<EffectControlLinearizationPhase>(); |
| 1311 RunPrintAndVerify("Effect and control linearized"); |
| 1312 } |
| 1313 |
1254 Run<BranchEliminationPhase>(); | 1314 Run<BranchEliminationPhase>(); |
1255 RunPrintAndVerify("Branch conditions eliminated"); | 1315 RunPrintAndVerify("Branch conditions eliminated"); |
1256 | 1316 |
1257 // Optimize control flow. | 1317 // Optimize control flow. |
1258 if (FLAG_turbo_cf_optimization) { | 1318 if (FLAG_turbo_cf_optimization) { |
1259 Run<ControlFlowOptimizationPhase>(); | 1319 Run<ControlFlowOptimizationPhase>(); |
1260 RunPrintAndVerify("Control flow optimized"); | 1320 RunPrintAndVerify("Control flow optimized"); |
1261 } | 1321 } |
1262 | 1322 |
1263 // Lower changes that have been inserted before. | 1323 // Lower changes that have been inserted before. |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1564 } | 1624 } |
1565 | 1625 |
1566 data->DeleteRegisterAllocationZone(); | 1626 data->DeleteRegisterAllocationZone(); |
1567 } | 1627 } |
1568 | 1628 |
1569 Isolate* Pipeline::isolate() const { return info()->isolate(); } | 1629 Isolate* Pipeline::isolate() const { return info()->isolate(); } |
1570 | 1630 |
1571 } // namespace compiler | 1631 } // namespace compiler |
1572 } // namespace internal | 1632 } // namespace internal |
1573 } // namespace v8 | 1633 } // namespace v8 |
OLD | NEW |