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

Side by Side Diff: src/compiler/pipeline.cc

Issue 727323002: [turbofan] move register allocation phases to pipeline (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 6 years, 1 month 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
« no previous file with comments | « src/compiler/pipeline.h ('k') | src/compiler/register-allocator.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/platform/elapsed-timer.h" 10 #include "src/base/platform/elapsed-timer.h"
(...skipping 25 matching lines...) Expand all
36 #include "src/compiler/zone-pool.h" 36 #include "src/compiler/zone-pool.h"
37 #include "src/ostreams.h" 37 #include "src/ostreams.h"
38 #include "src/utils.h" 38 #include "src/utils.h"
39 39
40 namespace v8 { 40 namespace v8 {
41 namespace internal { 41 namespace internal {
42 namespace compiler { 42 namespace compiler {
43 43
44 class PipelineData { 44 class PipelineData {
45 public: 45 public:
46 PipelineData(CompilationInfo* info, ZonePool* zone_pool, 46 explicit PipelineData(ZonePool* zone_pool, CompilationInfo* info)
47 PipelineStatistics* pipeline_statistics)
48 : isolate_(info->zone()->isolate()), 47 : isolate_(info->zone()->isolate()),
49 info_(info), 48 info_(info),
50 outer_zone_(info->zone()),
51 zone_pool_(zone_pool),
52 pipeline_statistics_(pipeline_statistics),
53 compilation_failed_(false),
54 code_(Handle<Code>::null()),
55 graph_zone_scope_(zone_pool_),
56 graph_zone_(graph_zone_scope_.zone()),
57 graph_(new (graph_zone()) Graph(graph_zone())),
58 source_positions_(new SourcePositionTable(graph())),
59 machine_(new (graph_zone()) MachineOperatorBuilder(
60 graph_zone(), kMachPtr,
61 InstructionSelector::SupportedMachineOperatorFlags())),
62 common_(new (graph_zone()) CommonOperatorBuilder(graph_zone())),
63 javascript_(new (graph_zone()) JSOperatorBuilder(graph_zone())),
64 jsgraph_(new (graph_zone())
65 JSGraph(graph(), common(), javascript(), machine())),
66 typer_(new Typer(graph(), info->context())),
67 context_node_(nullptr),
68 schedule_(nullptr),
69 instruction_zone_scope_(zone_pool_),
70 instruction_zone_(instruction_zone_scope_.zone()),
71 sequence_(nullptr),
72 frame_(nullptr) {}
73
74
75 // For machine graph testing only.
76 PipelineData(Graph* graph, Schedule* schedule, ZonePool* zone_pool)
77 : isolate_(graph->zone()->isolate()),
78 info_(nullptr),
79 outer_zone_(nullptr), 49 outer_zone_(nullptr),
80 zone_pool_(zone_pool), 50 zone_pool_(zone_pool),
81 pipeline_statistics_(nullptr), 51 pipeline_statistics_(nullptr),
82 compilation_failed_(false), 52 compilation_failed_(false),
83 code_(Handle<Code>::null()), 53 code_(Handle<Code>::null()),
84 graph_zone_scope_(zone_pool_), 54 graph_zone_scope_(zone_pool_),
85 graph_zone_(nullptr), 55 graph_zone_(nullptr),
86 graph_(graph), 56 graph_(nullptr),
87 source_positions_(new SourcePositionTable(graph)),
88 machine_(nullptr), 57 machine_(nullptr),
89 common_(nullptr), 58 common_(nullptr),
90 javascript_(nullptr), 59 javascript_(nullptr),
91 jsgraph_(nullptr), 60 jsgraph_(nullptr),
92 typer_(nullptr), 61 typer_(nullptr),
93 context_node_(nullptr), 62 context_node_(nullptr),
94 schedule_(schedule), 63 schedule_(nullptr),
95 instruction_zone_scope_(zone_pool_), 64 instruction_zone_scope_(zone_pool_),
96 instruction_zone_(instruction_zone_scope_.zone()), 65 instruction_zone_(nullptr),
97 sequence_(nullptr), 66 sequence_(nullptr),
98 frame_(nullptr) {} 67 frame_(nullptr),
68 register_allocator_(nullptr) {}
99 69
100 ~PipelineData() { 70 ~PipelineData() {
101 DeleteInstructionZone(); 71 DeleteInstructionZone();
102 DeleteGraphZone(); 72 DeleteGraphZone();
103 } 73 }
104 74
75 // For main entry point.
76 void Initialize(PipelineStatistics* pipeline_statistics) {
77 outer_zone_ = info()->zone();
78 pipeline_statistics_ = pipeline_statistics;
79 graph_zone_ = graph_zone_scope_.zone();
80 graph_ = new (graph_zone()) Graph(graph_zone());
81 source_positions_.Reset(new SourcePositionTable(graph()));
82 machine_ = new (graph_zone()) MachineOperatorBuilder(
83 graph_zone(), kMachPtr,
84 InstructionSelector::SupportedMachineOperatorFlags());
85 common_ = new (graph_zone()) CommonOperatorBuilder(graph_zone());
86 javascript_ = new (graph_zone()) JSOperatorBuilder(graph_zone());
87 jsgraph_ =
88 new (graph_zone()) JSGraph(graph(), common(), javascript(), machine());
89 typer_.Reset(new Typer(graph(), info()->context()));
90 instruction_zone_ = instruction_zone_scope_.zone();
91 }
92
93 // For machine graph testing entry point.
94 void Initialize(Graph* graph, Schedule* schedule) {
Benedikt Meurer 2014/11/17 11:35:28 append ForTesting to name.
95 graph_ = graph;
96 source_positions_.Reset(new SourcePositionTable(graph));
97 schedule_ = schedule;
98 instruction_zone_ = instruction_zone_scope_.zone();
99 }
100
101 // For register allocation entry point.
102 void Initialize(InstructionSequence* sequence) {
103 instruction_zone_ = sequence->zone();
104 sequence_ = sequence;
105 }
106
105 Isolate* isolate() const { return isolate_; } 107 Isolate* isolate() const { return isolate_; }
106 CompilationInfo* info() const { return info_; } 108 CompilationInfo* info() const { return info_; }
107 ZonePool* zone_pool() const { return zone_pool_; } 109 ZonePool* zone_pool() const { return zone_pool_; }
108 PipelineStatistics* pipeline_statistics() { return pipeline_statistics_; } 110 PipelineStatistics* pipeline_statistics() { return pipeline_statistics_; }
109 bool compilation_failed() const { return compilation_failed_; } 111 bool compilation_failed() const { return compilation_failed_; }
110 void set_compilation_failed() { compilation_failed_ = true; } 112 void set_compilation_failed() { compilation_failed_ = true; }
111 Handle<Code> code() { return code_; } 113 Handle<Code> code() { return code_; }
112 void set_code(Handle<Code> code) { 114 void set_code(Handle<Code> code) {
113 DCHECK(code_.is_null()); 115 DCHECK(code_.is_null());
114 code_ = code; 116 code_ = code;
(...skipping 20 matching lines...) Expand all
135 } 137 }
136 138
137 Schedule* schedule() const { return schedule_; } 139 Schedule* schedule() const { return schedule_; }
138 void set_schedule(Schedule* schedule) { 140 void set_schedule(Schedule* schedule) {
139 DCHECK_EQ(nullptr, schedule_); 141 DCHECK_EQ(nullptr, schedule_);
140 schedule_ = schedule; 142 schedule_ = schedule;
141 } 143 }
142 144
143 Zone* instruction_zone() const { return instruction_zone_; } 145 Zone* instruction_zone() const { return instruction_zone_; }
144 InstructionSequence* sequence() const { return sequence_; } 146 InstructionSequence* sequence() const { return sequence_; }
145 void set_sequence(InstructionSequence* sequence) {
146 DCHECK_EQ(nullptr, sequence_);
147 sequence_ = sequence;
148 }
149 Frame* frame() const { return frame_; } 147 Frame* frame() const { return frame_; }
150 void set_frame(Frame* frame) { 148 RegisterAllocator* register_allocator() const { return register_allocator_; }
151 DCHECK_EQ(nullptr, frame_);
152 frame_ = frame;
153 }
154 149
155 void DeleteGraphZone() { 150 void DeleteGraphZone() {
156 // Destroy objects with destructors first. 151 // Destroy objects with destructors first.
157 source_positions_.Reset(nullptr); 152 source_positions_.Reset(nullptr);
158 typer_.Reset(nullptr); 153 typer_.Reset(nullptr);
159 if (graph_zone_ == nullptr) return; 154 if (graph_zone_ == nullptr) return;
160 // Destroy zone and clear pointers. 155 // Destroy zone and clear pointers.
161 graph_zone_scope_.Destroy(); 156 graph_zone_scope_.Destroy();
162 graph_zone_ = nullptr; 157 graph_zone_ = nullptr;
163 graph_ = nullptr; 158 graph_ = nullptr;
164 machine_ = nullptr; 159 machine_ = nullptr;
165 common_ = nullptr; 160 common_ = nullptr;
166 javascript_ = nullptr; 161 javascript_ = nullptr;
167 jsgraph_ = nullptr; 162 jsgraph_ = nullptr;
168 context_node_ = nullptr; 163 context_node_ = nullptr;
169 schedule_ = nullptr; 164 schedule_ = nullptr;
170 } 165 }
171 166
172 void DeleteInstructionZone() { 167 void DeleteInstructionZone() {
173 if (instruction_zone_ == nullptr) return; 168 if (instruction_zone_ == nullptr) return;
174 instruction_zone_scope_.Destroy(); 169 instruction_zone_scope_.Destroy();
175 instruction_zone_ = nullptr; 170 instruction_zone_ = nullptr;
176 sequence_ = nullptr; 171 sequence_ = nullptr;
177 frame_ = nullptr; 172 frame_ = nullptr;
173 register_allocator_ = nullptr;
174 }
175
176 void InitializeInstructionSequence() {
177 DCHECK_EQ(nullptr, sequence_);
178 InstructionBlocks* instruction_blocks =
179 InstructionSequence::InstructionBlocksFor(instruction_zone(),
180 schedule());
181 sequence_ = new (instruction_zone())
182 InstructionSequence(instruction_zone(), instruction_blocks);
183 }
184
185 void InitializeRegisterAllocator(Zone* local_zone,
186 const RegisterConfiguration* config,
187 const char* debug_name) {
188 DCHECK_EQ(nullptr, register_allocator_);
189 DCHECK_EQ(nullptr, frame_);
190 frame_ = new (instruction_zone()) Frame();
191 register_allocator_ = new (instruction_zone())
192 RegisterAllocator(config, local_zone, frame(), sequence(), debug_name);
178 } 193 }
179 194
180 private: 195 private:
181 Isolate* isolate_; 196 Isolate* isolate_;
182 CompilationInfo* info_; 197 CompilationInfo* info_;
183 Zone* outer_zone_; 198 Zone* outer_zone_;
184 ZonePool* zone_pool_; 199 ZonePool* const zone_pool_;
185 PipelineStatistics* pipeline_statistics_; 200 PipelineStatistics* pipeline_statistics_;
186 bool compilation_failed_; 201 bool compilation_failed_;
187 Handle<Code> code_; 202 Handle<Code> code_;
188 203
189 ZonePool::Scope graph_zone_scope_; 204 ZonePool::Scope graph_zone_scope_;
190 Zone* graph_zone_; 205 Zone* graph_zone_;
191 // All objects in the following group of fields are allocated in graph_zone_. 206 // All objects in the following group of fields are allocated in graph_zone_.
192 // They are all set to NULL when the graph_zone_ is destroyed. 207 // They are all set to NULL when the graph_zone_ is destroyed.
193 Graph* graph_; 208 Graph* graph_;
194 // TODO(dcarney): make this into a ZoneObject. 209 // TODO(dcarney): make this into a ZoneObject.
195 SmartPointer<SourcePositionTable> source_positions_; 210 SmartPointer<SourcePositionTable> source_positions_;
196 MachineOperatorBuilder* machine_; 211 MachineOperatorBuilder* machine_;
197 CommonOperatorBuilder* common_; 212 CommonOperatorBuilder* common_;
198 JSOperatorBuilder* javascript_; 213 JSOperatorBuilder* javascript_;
199 JSGraph* jsgraph_; 214 JSGraph* jsgraph_;
200 // TODO(dcarney): make this into a ZoneObject. 215 // TODO(dcarney): make this into a ZoneObject.
201 SmartPointer<Typer> typer_; 216 SmartPointer<Typer> typer_;
202 Node* context_node_; 217 Node* context_node_;
203 Schedule* schedule_; 218 Schedule* schedule_;
204 219
205 // All objects in the following group of fields are allocated in 220 // All objects in the following group of fields are allocated in
206 // instruction_zone_. They are all set to NULL when the instruction_zone_ is 221 // instruction_zone_. They are all set to NULL when the instruction_zone_ is
207 // destroyed. 222 // destroyed.
208 ZonePool::Scope instruction_zone_scope_; 223 ZonePool::Scope instruction_zone_scope_;
209 Zone* instruction_zone_; 224 Zone* instruction_zone_;
210 InstructionSequence* sequence_; 225 InstructionSequence* sequence_;
211 Frame* frame_; 226 Frame* frame_;
227 RegisterAllocator* register_allocator_;
212 228
213 DISALLOW_COPY_AND_ASSIGN(PipelineData); 229 DISALLOW_COPY_AND_ASSIGN(PipelineData);
214 }; 230 };
215 231
216 232
217 static inline bool VerifyGraphs() { 233 static inline bool VerifyGraphs() {
218 #ifdef DEBUG 234 #ifdef DEBUG
219 return true; 235 return true;
220 #else 236 #else
221 return FLAG_turbo_verify; 237 return FLAG_turbo_verify;
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 326
311 327
312 template <typename Phase, typename Arg0> 328 template <typename Phase, typename Arg0>
313 void Pipeline::Run(Arg0 arg_0) { 329 void Pipeline::Run(Arg0 arg_0) {
314 PipelineRunScope scope(this->data_, Phase::phase_name()); 330 PipelineRunScope scope(this->data_, Phase::phase_name());
315 Phase phase; 331 Phase phase;
316 phase.Run(this->data_, scope.zone(), arg_0); 332 phase.Run(this->data_, scope.zone(), arg_0);
317 } 333 }
318 334
319 335
320 // TODO(dcarney): this one should be unecessary.
321 template <typename Phase, typename Arg0, typename Arg1>
322 void Pipeline::Run(Arg0 arg_0, Arg1 arg_1) {
323 PipelineRunScope scope(this->data_, Phase::phase_name());
324 Phase phase;
325 phase.Run(this->data_, scope.zone(), arg_0, arg_1);
326 }
327
328
329 struct GraphBuilderPhase { 336 struct GraphBuilderPhase {
330 static const char* phase_name() { return "graph builder"; } 337 static const char* phase_name() { return "graph builder"; }
331 338
332 void Run(PipelineData* data, Zone* temp_zone) { 339 void Run(PipelineData* data, Zone* temp_zone) {
333 AstGraphBuilderWithPositions graph_builder( 340 AstGraphBuilderWithPositions graph_builder(
334 temp_zone, data->info(), data->jsgraph(), data->source_positions()); 341 temp_zone, data->info(), data->jsgraph(), data->source_positions());
335 if (graph_builder.CreateGraph()) { 342 if (graph_builder.CreateGraph()) {
336 data->set_context_node(graph_builder.GetFunctionContext()); 343 data->set_context_node(graph_builder.GetFunctionContext());
337 } else { 344 } else {
338 data->set_compilation_failed(); 345 data->set_compilation_failed();
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 490
484 void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage) { 491 void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage) {
485 InstructionSelector selector(temp_zone, data->graph(), linkage, 492 InstructionSelector selector(temp_zone, data->graph(), linkage,
486 data->sequence(), data->schedule(), 493 data->sequence(), data->schedule(),
487 data->source_positions()); 494 data->source_positions());
488 selector.SelectInstructions(); 495 selector.SelectInstructions();
489 } 496 }
490 }; 497 };
491 498
492 499
493 // TODO(dcarney): break this up. 500 struct MeetRegisterConstraintsPhase {
494 struct RegisterAllocationPhase { 501 static const char* phase_name() { return "meet register constraints"; }
495 static const char* phase_name() { return nullptr; }
496 502
497 void Run(PipelineData* data, Zone* temp_zone) { 503 void Run(PipelineData* data, Zone* temp_zone) {
498 int node_count = data->sequence()->VirtualRegisterCount(); 504 data->register_allocator()->MeetRegisterConstraints();
499 if (node_count > UnallocatedOperand::kMaxVirtualRegisters) {
500 data->set_compilation_failed();
501 return;
502 }
503
504 SmartArrayPointer<char> debug_name;
505 #ifdef DEBUG
506 if (data->info() != nullptr) {
507 debug_name = GetDebugName(data->info());
508 }
509 #endif
510
511 RegisterAllocator allocator(RegisterConfiguration::ArchDefault(), temp_zone,
512 data->frame(), data->sequence(),
513 debug_name.get());
514
515 if (!allocator.Allocate(data->pipeline_statistics())) {
516 data->set_compilation_failed();
517 return;
518 }
519
520 if (FLAG_trace_turbo) {
521 OFStream os(stdout);
522 PrintableInstructionSequence printable = {
523 RegisterConfiguration::ArchDefault(), data->sequence()};
524 os << "----- Instruction sequence after register allocation -----\n"
525 << printable;
526 }
527
528 if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) {
529 TurboCfgFile tcf(data->isolate());
530 tcf << AsC1VAllocator("CodeGen", &allocator);
531 }
532 } 505 }
533 }; 506 };
534 507
508
509 struct ResolvePhisPhase {
510 static const char* phase_name() { return "resolve phis"; }
511
512 void Run(PipelineData* data, Zone* temp_zone) {
513 data->register_allocator()->ResolvePhis();
514 }
515 };
516
517
518 struct BuildLiveRangesPhase {
519 static const char* phase_name() { return "build live ranges"; }
520
521 void Run(PipelineData* data, Zone* temp_zone) {
522 data->register_allocator()->BuildLiveRanges();
523 }
524 };
525
526
527 struct AllocateGeneralRegistersPhase {
528 static const char* phase_name() { return "allocate general registers"; }
529
530 void Run(PipelineData* data, Zone* temp_zone) {
531 data->register_allocator()->AllocateGeneralRegisters();
532 }
533 };
534
535
536 struct AllocateDoubleRegistersPhase {
537 static const char* phase_name() { return "allocate double registers"; }
538
539 void Run(PipelineData* data, Zone* temp_zone) {
540 data->register_allocator()->AllocateDoubleRegisters();
541 }
542 };
543
544
545 struct PopulatePointerMapsPhase {
546 static const char* phase_name() { return "populate pointer maps"; }
547
548 void Run(PipelineData* data, Zone* temp_zone) {
549 data->register_allocator()->PopulatePointerMaps();
550 }
551 };
552
553
554 struct ConnectRangesPhase {
555 static const char* phase_name() { return "connect ranges"; }
556
557 void Run(PipelineData* data, Zone* temp_zone) {
558 data->register_allocator()->ConnectRanges();
559 }
560 };
561
562
563 struct ResolveControlFlowPhase {
564 static const char* phase_name() { return "resolve control flow"; }
565
566 void Run(PipelineData* data, Zone* temp_zone) {
567 data->register_allocator()->ResolveControlFlow();
568 }
569 };
570
535 571
536 struct GenerateCodePhase { 572 struct GenerateCodePhase {
537 static const char* phase_name() { return "generate code"; } 573 static const char* phase_name() { return "generate code"; }
538 574
539 void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage, 575 void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage) {
540 CompilationInfo* info) { 576 CodeGenerator generator(data->frame(), linkage, data->sequence(),
541 CodeGenerator generator(data->frame(), linkage, data->sequence(), info); 577 data->info());
542 data->set_code(generator.GenerateCode()); 578 data->set_code(generator.GenerateCode());
543 } 579 }
544 }; 580 };
545 581
546 582
547 struct PrintGraphPhase { 583 struct PrintGraphPhase {
548 static const char* phase_name() { return nullptr; } 584 static const char* phase_name() { return nullptr; }
549 585
550 void Run(PipelineData* data, Zone* temp_zone, const char* phase) { 586 void Run(PipelineData* data, Zone* temp_zone, const char* phase) {
551 CompilationInfo* info = data->info(); 587 CompilationInfo* info = data->info();
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 static const char* phase_name() { return nullptr; } 629 static const char* phase_name() { return nullptr; }
594 630
595 void Run(PipelineData* data, Zone* temp_zone, const bool untyped) { 631 void Run(PipelineData* data, Zone* temp_zone, const bool untyped) {
596 Verifier::Run(data->graph(), FLAG_turbo_types && !untyped 632 Verifier::Run(data->graph(), FLAG_turbo_types && !untyped
597 ? Verifier::TYPED 633 ? Verifier::TYPED
598 : Verifier::UNTYPED); 634 : Verifier::UNTYPED);
599 } 635 }
600 }; 636 };
601 637
602 638
639 void Pipeline::BeginPhaseKind(const char* phase_kind_name) {
640 if (data_->pipeline_statistics() != NULL) {
641 data_->pipeline_statistics()->BeginPhaseKind("phase_kind_name");
642 }
643 }
644
645
603 void Pipeline::RunPrintAndVerify(const char* phase, bool untyped) { 646 void Pipeline::RunPrintAndVerify(const char* phase, bool untyped) {
604 if (FLAG_trace_turbo) { 647 if (FLAG_trace_turbo) {
605 Run<PrintGraphPhase>(phase); 648 Run<PrintGraphPhase>(phase);
606 } 649 }
607 if (VerifyGraphs()) { 650 if (VerifyGraphs()) {
608 Run<VerifyGraphPhase>(untyped); 651 Run<VerifyGraphPhase>(untyped);
609 } 652 }
610 } 653 }
611 654
612 655
(...skipping 10 matching lines...) Expand all
623 // TODO(turbofan): Make OSR work and remove this bailout. 666 // TODO(turbofan): Make OSR work and remove this bailout.
624 info()->is_osr()) { 667 info()->is_osr()) {
625 return Handle<Code>::null(); 668 return Handle<Code>::null();
626 } 669 }
627 670
628 ZonePool zone_pool(isolate()); 671 ZonePool zone_pool(isolate());
629 SmartPointer<PipelineStatistics> pipeline_statistics; 672 SmartPointer<PipelineStatistics> pipeline_statistics;
630 673
631 if (FLAG_turbo_stats) { 674 if (FLAG_turbo_stats) {
632 pipeline_statistics.Reset(new PipelineStatistics(info(), &zone_pool)); 675 pipeline_statistics.Reset(new PipelineStatistics(info(), &zone_pool));
633 pipeline_statistics->BeginPhaseKind("graph creation");
634 } 676 }
635 677
636 PipelineData data(info(), &zone_pool, pipeline_statistics.get()); 678 PipelineData data(&zone_pool, info());
637 this->data_ = &data; 679 this->data_ = &data;
638 680
681 BeginPhaseKind("graph creation");
682 data.Initialize(pipeline_statistics.get());
683
639 if (FLAG_trace_turbo) { 684 if (FLAG_trace_turbo) {
640 OFStream os(stdout); 685 OFStream os(stdout);
641 os << "---------------------------------------------------\n" 686 os << "---------------------------------------------------\n"
642 << "Begin compiling method " << GetDebugName(info()).get() 687 << "Begin compiling method " << GetDebugName(info()).get()
643 << " using Turbofan" << std::endl; 688 << " using Turbofan" << std::endl;
644 TurboCfgFile tcf(isolate()); 689 TurboCfgFile tcf(isolate());
645 tcf << AsC1VCompilation(info()); 690 tcf << AsC1VCompilation(info());
646 } 691 }
647 692
648 data.source_positions()->AddDecorator(); 693 data.source_positions()->AddDecorator();
(...skipping 23 matching lines...) Expand all
672 717
673 // Bailout here in case target architecture is not supported. 718 // Bailout here in case target architecture is not supported.
674 if (!SupportedTarget()) return Handle<Code>::null(); 719 if (!SupportedTarget()) return Handle<Code>::null();
675 720
676 if (info()->is_typing_enabled()) { 721 if (info()->is_typing_enabled()) {
677 // Type the graph. 722 // Type the graph.
678 Run<TyperPhase>(); 723 Run<TyperPhase>();
679 RunPrintAndVerify("Typed"); 724 RunPrintAndVerify("Typed");
680 } 725 }
681 726
682 if (!pipeline_statistics.is_empty()) { 727 BeginPhaseKind("lowering");
683 data.pipeline_statistics()->BeginPhaseKind("lowering");
684 }
685 728
686 if (info()->is_typing_enabled()) { 729 if (info()->is_typing_enabled()) {
687 // Lower JSOperators where we can determine types. 730 // Lower JSOperators where we can determine types.
688 Run<TypedLoweringPhase>(); 731 Run<TypedLoweringPhase>();
689 RunPrintAndVerify("Lowered typed"); 732 RunPrintAndVerify("Lowered typed");
690 733
691 // Lower simplified operators and insert changes. 734 // Lower simplified operators and insert changes.
692 Run<SimplifiedLoweringPhase>(); 735 Run<SimplifiedLoweringPhase>();
693 RunPrintAndVerify("Lowered simplified"); 736 RunPrintAndVerify("Lowered simplified");
694 737
695 // Lower changes that have been inserted before. 738 // Lower changes that have been inserted before.
696 Run<ChangeLoweringPhase>(); 739 Run<ChangeLoweringPhase>();
697 // // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. 740 // // TODO(jarin, rossberg): Remove UNTYPED once machine typing works.
698 RunPrintAndVerify("Lowered changes", true); 741 RunPrintAndVerify("Lowered changes", true);
699 742
700 Run<LateControlReductionPhase>(); 743 Run<LateControlReductionPhase>();
701 RunPrintAndVerify("Late Control reduced"); 744 RunPrintAndVerify("Late Control reduced");
702 } 745 }
703 746
704 // Lower any remaining generic JSOperators. 747 // Lower any remaining generic JSOperators.
705 Run<GenericLoweringPhase>(); 748 Run<GenericLoweringPhase>();
706 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. 749 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works.
707 RunPrintAndVerify("Lowered generic", true); 750 RunPrintAndVerify("Lowered generic", true);
708 751
709 if (!pipeline_statistics.is_empty()) { 752 BeginPhaseKind("block building");
710 data.pipeline_statistics()->BeginPhaseKind("block building");
711 }
712 753
713 data.source_positions()->RemoveDecorator(); 754 data.source_positions()->RemoveDecorator();
714 755
715 // Compute a schedule. 756 // Compute a schedule.
716 Run<ComputeSchedulePhase>(); 757 Run<ComputeSchedulePhase>();
717 758
718 { 759 {
719 // Generate optimized code. 760 // Generate optimized code.
720 Linkage linkage(data.instruction_zone(), info()); 761 Linkage linkage(data.instruction_zone(), info());
721 GenerateCode(&linkage); 762 GenerateCode(&linkage);
(...skipping 13 matching lines...) Expand all
735 776
736 return code; 777 return code;
737 } 778 }
738 779
739 780
740 Handle<Code> Pipeline::GenerateCodeForMachineGraph(Linkage* linkage, 781 Handle<Code> Pipeline::GenerateCodeForMachineGraph(Linkage* linkage,
741 Graph* graph, 782 Graph* graph,
742 Schedule* schedule) { 783 Schedule* schedule) {
743 ZonePool zone_pool(isolate()); 784 ZonePool zone_pool(isolate());
744 CHECK(SupportedBackend()); 785 CHECK(SupportedBackend());
745 PipelineData data(graph, schedule, &zone_pool); 786 PipelineData data(&zone_pool, info());
787 data.Initialize(graph, schedule);
746 this->data_ = &data; 788 this->data_ = &data;
747 if (schedule == NULL) { 789 if (schedule == NULL) {
748 // TODO(rossberg): Should this really be untyped? 790 // TODO(rossberg): Should this really be untyped?
749 RunPrintAndVerify("Machine", true); 791 RunPrintAndVerify("Machine", true);
750 Run<ComputeSchedulePhase>(); 792 Run<ComputeSchedulePhase>();
751 } else { 793 } else {
752 TraceSchedule(schedule); 794 TraceSchedule(schedule);
753 } 795 }
754 796
755 GenerateCode(linkage); 797 GenerateCode(linkage);
756 Handle<Code> code = data.code(); 798 Handle<Code> code = data.code();
757 799
758 #if ENABLE_DISASSEMBLER 800 #if ENABLE_DISASSEMBLER
759 if (!code.is_null() && FLAG_print_opt_code) { 801 if (!code.is_null() && FLAG_print_opt_code) {
760 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer()); 802 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer());
761 OFStream os(tracing_scope.file()); 803 OFStream os(tracing_scope.file());
762 code->Disassemble("test code", os); 804 code->Disassemble("test code", os);
763 } 805 }
764 #endif 806 #endif
765 return code; 807 return code;
766 } 808 }
767 809
768 810
811 bool Pipeline::AllocateRegisters(const RegisterConfiguration* config,
812 InstructionSequence* sequence,
813 bool run_verifier) {
814 CompilationInfo info(sequence->zone()->isolate(), sequence->zone());
815 ZonePool zone_pool(sequence->zone()->isolate());
816 PipelineData data(&zone_pool, &info);
817 data.Initialize(sequence);
818 Pipeline pipeline(&info);
819 pipeline.data_ = &data;
820 pipeline.AllocateRegisters(config, run_verifier);
821 return !data.compilation_failed();
822 }
823
824
769 void Pipeline::GenerateCode(Linkage* linkage) { 825 void Pipeline::GenerateCode(Linkage* linkage) {
770 PipelineData* data = this->data_; 826 PipelineData* data = this->data_;
771 827
772 DCHECK_NOT_NULL(linkage); 828 DCHECK_NOT_NULL(linkage);
773 DCHECK_NOT_NULL(data->graph()); 829 DCHECK_NOT_NULL(data->graph());
774 DCHECK_NOT_NULL(data->schedule()); 830 DCHECK_NOT_NULL(data->schedule());
775 CHECK(SupportedBackend()); 831 CHECK(SupportedBackend());
776 832
777 BasicBlockProfiler::Data* profiler_data = NULL; 833 BasicBlockProfiler::Data* profiler_data = NULL;
778 if (FLAG_turbo_profiling) { 834 if (FLAG_turbo_profiling) {
779 profiler_data = BasicBlockInstrumentor::Instrument(info(), data->graph(), 835 profiler_data = BasicBlockInstrumentor::Instrument(info(), data->graph(),
780 data->schedule()); 836 data->schedule());
781 } 837 }
782 838
783 InstructionBlocks* instruction_blocks = 839 data->InitializeInstructionSequence();
784 InstructionSequence::InstructionBlocksFor(data->instruction_zone(),
785 data->schedule());
786 data->set_sequence(new (data->instruction_zone()) InstructionSequence(
787 data->instruction_zone(), instruction_blocks));
788 840
789 // Select and schedule instructions covering the scheduled graph. 841 // Select and schedule instructions covering the scheduled graph.
790 Run<InstructionSelectionPhase>(linkage); 842 Run<InstructionSelectionPhase>(linkage);
791 843
792 if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) { 844 if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) {
793 TurboCfgFile tcf(isolate()); 845 TurboCfgFile tcf(isolate());
794 tcf << AsC1V("CodeGen", data->schedule(), data->source_positions(), 846 tcf << AsC1V("CodeGen", data->schedule(), data->source_positions(),
795 data->sequence()); 847 data->sequence());
796 } 848 }
797 849
798 data->DeleteGraphZone(); 850 data->DeleteGraphZone();
799 851
800 if (data->pipeline_statistics() != NULL) { 852 BeginPhaseKind("register allocation");
801 data->pipeline_statistics()->BeginPhaseKind("register allocation");
802 }
803 853
854 bool run_verifier = false;
804 #ifdef DEBUG 855 #ifdef DEBUG
805 // Don't track usage for this zone in compiler stats. 856 run_verifier = true;
806 Zone verifier_zone(info()->isolate());
807 RegisterAllocatorVerifier verifier(
808 &verifier_zone, RegisterConfiguration::ArchDefault(), data->sequence());
809 #endif 857 #endif
810
811 // Allocate registers. 858 // Allocate registers.
812 data->set_frame(new (data->instruction_zone()) Frame); 859 AllocateRegisters(RegisterConfiguration::ArchDefault(), run_verifier);
813 Run<RegisterAllocationPhase>();
814 if (data->compilation_failed()) { 860 if (data->compilation_failed()) {
815 info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc); 861 info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc);
816 return; 862 return;
817 } 863 }
818 864
819 #ifdef DEBUG 865 BeginPhaseKind("code generation");
820 verifier.VerifyAssignment();
821 verifier.VerifyGapMoves();
822 #endif
823
824 if (data->pipeline_statistics() != NULL) {
825 data->pipeline_statistics()->BeginPhaseKind("code generation");
826 }
827 866
828 // Generate native sequence. 867 // Generate native sequence.
829 Run<GenerateCodePhase>(linkage, info()); 868 Run<GenerateCodePhase>(linkage);
830 869
831 if (profiler_data != NULL) { 870 if (profiler_data != NULL) {
832 #if ENABLE_DISASSEMBLER 871 #if ENABLE_DISASSEMBLER
833 std::ostringstream os; 872 std::ostringstream os;
834 data->code()->Disassemble(NULL, os); 873 data->code()->Disassemble(NULL, os);
835 profiler_data->SetCode(&os); 874 profiler_data->SetCode(&os);
836 #endif 875 #endif
837 } 876 }
838 } 877 }
839 878
840 879
880 void Pipeline::AllocateRegisters(const RegisterConfiguration* config,
881 bool run_verifier) {
882 PipelineData* data = this->data_;
883
884 int node_count = data->sequence()->VirtualRegisterCount();
885 if (node_count > UnallocatedOperand::kMaxVirtualRegisters) {
886 data->set_compilation_failed();
887 return;
888 }
889
890 // Don't track usage for this zone in compiler stats.
891 SmartPointer<Zone> verifier_zone;
892 RegisterAllocatorVerifier* verifier = nullptr;
893 if (run_verifier) {
894 verifier_zone.Reset(new Zone(info()->isolate()));
895 verifier = new (verifier_zone.get()) RegisterAllocatorVerifier(
896 verifier_zone.get(), config, data->sequence());
897 }
898
899 SmartArrayPointer<char> debug_name;
900 #ifdef DEBUG
901 debug_name = GetDebugName(data->info());
902 #endif
903
904 ZonePool::Scope zone_scope(data->zone_pool());
905 data->InitializeRegisterAllocator(zone_scope.zone(), config,
906 debug_name.get());
907
908 Run<MeetRegisterConstraintsPhase>();
909 Run<ResolvePhisPhase>();
910 Run<BuildLiveRangesPhase>();
911 if (FLAG_trace_turbo) {
912 OFStream os(stdout);
913 PrintableInstructionSequence printable = {config, data->sequence()};
914 os << "----- Instruction sequence before register allocation -----\n"
915 << printable;
916 }
917 DCHECK(!data->register_allocator()->ExistsUseWithoutDefinition());
918 Run<AllocateGeneralRegistersPhase>();
919 if (!data->register_allocator()->AllocationOk()) {
920 data->set_compilation_failed();
921 return;
922 }
923 Run<AllocateDoubleRegistersPhase>();
924 if (!data->register_allocator()->AllocationOk()) {
925 data->set_compilation_failed();
926 return;
927 }
928 Run<PopulatePointerMapsPhase>();
929 Run<ConnectRangesPhase>();
930 Run<ResolveControlFlowPhase>();
931
932 if (FLAG_trace_turbo) {
933 OFStream os(stdout);
934 PrintableInstructionSequence printable = {config, data->sequence()};
935 os << "----- Instruction sequence after register allocation -----\n"
936 << printable;
937 }
938
939 if (verifier != nullptr) {
940 verifier->VerifyAssignment();
941 verifier->VerifyGapMoves();
942 }
943
944 if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) {
945 TurboCfgFile tcf(data->isolate());
946 tcf << AsC1VAllocator("CodeGen", data->register_allocator());
947 }
948 }
949
950
841 void Pipeline::SetUp() { 951 void Pipeline::SetUp() {
842 InstructionOperand::SetUpCaches(); 952 InstructionOperand::SetUpCaches();
843 } 953 }
844 954
845 955
846 void Pipeline::TearDown() { 956 void Pipeline::TearDown() {
847 InstructionOperand::TearDownCaches(); 957 InstructionOperand::TearDownCaches();
848 } 958 }
849 959
850 } // namespace compiler 960 } // namespace compiler
851 } // namespace internal 961 } // namespace internal
852 } // namespace v8 962 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/pipeline.h ('k') | src/compiler/register-allocator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698