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

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

Issue 727733002: [turbofan] refactor pipeline to use hydrogen like Run calls (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebase 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') | test/cctest/compiler/test-codegen-deopt.cc » ('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 explicit PipelineData(CompilationInfo* info, ZonePool* zone_pool, 46 PipelineData(CompilationInfo* info, ZonePool* zone_pool,
47 PipelineStatistics* pipeline_statistics) 47 PipelineStatistics* pipeline_statistics)
48 : isolate_(info->zone()->isolate()), 48 : isolate_(info->zone()->isolate()),
49 info_(info),
49 outer_zone_(info->zone()), 50 outer_zone_(info->zone()),
50 zone_pool_(zone_pool), 51 zone_pool_(zone_pool),
51 pipeline_statistics_(pipeline_statistics), 52 pipeline_statistics_(pipeline_statistics),
53 compilation_failed_(false),
54 code_(Handle<Code>::null()),
52 graph_zone_scope_(zone_pool_), 55 graph_zone_scope_(zone_pool_),
53 graph_zone_(graph_zone_scope_.zone()), 56 graph_zone_(graph_zone_scope_.zone()),
54 graph_(new (graph_zone()) Graph(graph_zone())), 57 graph_(new (graph_zone()) Graph(graph_zone())),
55 source_positions_(new SourcePositionTable(graph())), 58 source_positions_(new SourcePositionTable(graph())),
56 machine_(new (graph_zone()) MachineOperatorBuilder( 59 machine_(new (graph_zone()) MachineOperatorBuilder(
57 graph_zone(), kMachPtr, 60 graph_zone(), kMachPtr,
58 InstructionSelector::SupportedMachineOperatorFlags())), 61 InstructionSelector::SupportedMachineOperatorFlags())),
59 common_(new (graph_zone()) CommonOperatorBuilder(graph_zone())), 62 common_(new (graph_zone()) CommonOperatorBuilder(graph_zone())),
60 javascript_(new (graph_zone()) JSOperatorBuilder(graph_zone())), 63 javascript_(new (graph_zone()) JSOperatorBuilder(graph_zone())),
61 jsgraph_(new (graph_zone()) 64 jsgraph_(new (graph_zone())
62 JSGraph(graph(), common(), javascript(), machine())), 65 JSGraph(graph(), common(), javascript(), machine())),
63 typer_(new Typer(graph(), info->context())), 66 typer_(new Typer(graph(), info->context())),
64 schedule_(NULL), 67 context_node_(nullptr),
68 schedule_(nullptr),
65 instruction_zone_scope_(zone_pool_), 69 instruction_zone_scope_(zone_pool_),
66 instruction_zone_(instruction_zone_scope_.zone()) {} 70 instruction_zone_(instruction_zone_scope_.zone()),
71 sequence_(nullptr),
72 frame_(nullptr) {}
73
67 74
68 // For machine graph testing only. 75 // For machine graph testing only.
69 PipelineData(Graph* graph, Schedule* schedule, ZonePool* zone_pool) 76 PipelineData(Graph* graph, Schedule* schedule, ZonePool* zone_pool)
70 : isolate_(graph->zone()->isolate()), 77 : isolate_(graph->zone()->isolate()),
71 outer_zone_(NULL), 78 info_(nullptr),
79 outer_zone_(nullptr),
72 zone_pool_(zone_pool), 80 zone_pool_(zone_pool),
73 pipeline_statistics_(NULL), 81 pipeline_statistics_(nullptr),
82 compilation_failed_(false),
83 code_(Handle<Code>::null()),
74 graph_zone_scope_(zone_pool_), 84 graph_zone_scope_(zone_pool_),
75 graph_zone_(NULL), 85 graph_zone_(nullptr),
76 graph_(graph), 86 graph_(graph),
77 source_positions_(new SourcePositionTable(graph)), 87 source_positions_(new SourcePositionTable(graph)),
78 machine_(NULL), 88 machine_(nullptr),
79 common_(NULL), 89 common_(nullptr),
80 javascript_(NULL), 90 javascript_(nullptr),
81 jsgraph_(NULL), 91 jsgraph_(nullptr),
82 typer_(NULL), 92 typer_(nullptr),
93 context_node_(nullptr),
83 schedule_(schedule), 94 schedule_(schedule),
84 instruction_zone_scope_(zone_pool_), 95 instruction_zone_scope_(zone_pool_),
85 instruction_zone_(instruction_zone_scope_.zone()) {} 96 instruction_zone_(instruction_zone_scope_.zone()),
97 sequence_(nullptr),
98 frame_(nullptr) {}
86 99
87 ~PipelineData() { 100 ~PipelineData() {
88 DeleteInstructionZone(); 101 DeleteInstructionZone();
89 DeleteGraphZone(); 102 DeleteGraphZone();
90 } 103 }
91 104
92 Isolate* isolate() const { return isolate_; } 105 Isolate* isolate() const { return isolate_; }
106 CompilationInfo* info() const { return info_; }
93 ZonePool* zone_pool() const { return zone_pool_; } 107 ZonePool* zone_pool() const { return zone_pool_; }
94 PipelineStatistics* pipeline_statistics() { return pipeline_statistics_; } 108 PipelineStatistics* pipeline_statistics() { return pipeline_statistics_; }
109 bool compilation_failed() const { return compilation_failed_; }
110 void set_compilation_failed() { compilation_failed_ = true; }
111 Handle<Code> code() { return code_; }
112 void set_code(Handle<Code> code) {
113 DCHECK(code_.is_null());
114 code_ = code;
115 }
116
117 // RawMachineAssembler generally produces graphs which cannot be verified.
118 bool MayHaveUnverifiableGraph() const { return outer_zone_ == nullptr; }
95 119
96 Zone* graph_zone() const { return graph_zone_; } 120 Zone* graph_zone() const { return graph_zone_; }
97 Graph* graph() const { return graph_; } 121 Graph* graph() const { return graph_; }
98 SourcePositionTable* source_positions() const { 122 SourcePositionTable* source_positions() const {
99 return source_positions_.get(); 123 return source_positions_.get();
100 } 124 }
101 MachineOperatorBuilder* machine() const { return machine_; } 125 MachineOperatorBuilder* machine() const { return machine_; }
102 CommonOperatorBuilder* common() const { return common_; } 126 CommonOperatorBuilder* common() const { return common_; }
103 JSOperatorBuilder* javascript() const { return javascript_; } 127 JSOperatorBuilder* javascript() const { return javascript_; }
104 JSGraph* jsgraph() const { return jsgraph_; } 128 JSGraph* jsgraph() const { return jsgraph_; }
105 Typer* typer() const { return typer_.get(); } 129 Typer* typer() const { return typer_.get(); }
130
131 Node* context_node() const { return context_node_; }
132 void set_context_node(Node* context_node) {
133 DCHECK_EQ(nullptr, context_node_);
134 context_node_ = context_node;
135 }
136
106 Schedule* schedule() const { return schedule_; } 137 Schedule* schedule() const { return schedule_; }
107 void set_schedule(Schedule* schedule) { 138 void set_schedule(Schedule* schedule) {
108 DCHECK_EQ(NULL, schedule_); 139 DCHECK_EQ(nullptr, schedule_);
109 schedule_ = schedule; 140 schedule_ = schedule;
110 } 141 }
111 142
112 Zone* instruction_zone() const { return instruction_zone_; } 143 Zone* instruction_zone() const { return instruction_zone_; }
113 // RawMachineAssembler generally produces graphs which cannot be verified. 144 InstructionSequence* sequence() const { return sequence_; }
114 bool MayHaveUnverifiableGraph() const { return outer_zone_ == nullptr; } 145 void set_sequence(InstructionSequence* sequence) {
146 DCHECK_EQ(nullptr, sequence_);
147 sequence_ = sequence;
148 }
149 Frame* frame() const { return frame_; }
150 void set_frame(Frame* frame) {
151 DCHECK_EQ(nullptr, frame_);
152 frame_ = frame;
153 }
115 154
116 void DeleteGraphZone() { 155 void DeleteGraphZone() {
117 // Destroy objects with destructors first. 156 // Destroy objects with destructors first.
118 source_positions_.Reset(NULL); 157 source_positions_.Reset(nullptr);
119 typer_.Reset(NULL); 158 typer_.Reset(nullptr);
120 if (graph_zone_ == NULL) return; 159 if (graph_zone_ == nullptr) return;
121 // Destroy zone and clear pointers. 160 // Destroy zone and clear pointers.
122 graph_zone_scope_.Destroy(); 161 graph_zone_scope_.Destroy();
123 graph_zone_ = NULL; 162 graph_zone_ = nullptr;
124 graph_ = NULL; 163 graph_ = nullptr;
125 machine_ = NULL; 164 machine_ = nullptr;
126 common_ = NULL; 165 common_ = nullptr;
127 javascript_ = NULL; 166 javascript_ = nullptr;
128 jsgraph_ = NULL; 167 jsgraph_ = nullptr;
129 schedule_ = NULL; 168 context_node_ = nullptr;
169 schedule_ = nullptr;
130 } 170 }
131 171
132 void DeleteInstructionZone() { 172 void DeleteInstructionZone() {
133 if (instruction_zone_ == NULL) return; 173 if (instruction_zone_ == nullptr) return;
134 instruction_zone_scope_.Destroy(); 174 instruction_zone_scope_.Destroy();
135 instruction_zone_ = NULL; 175 instruction_zone_ = nullptr;
176 sequence_ = nullptr;
177 frame_ = nullptr;
136 } 178 }
137 179
138 private: 180 private:
139 Isolate* isolate_; 181 Isolate* isolate_;
182 CompilationInfo* info_;
140 Zone* outer_zone_; 183 Zone* outer_zone_;
141 ZonePool* zone_pool_; 184 ZonePool* zone_pool_;
142 PipelineStatistics* pipeline_statistics_; 185 PipelineStatistics* pipeline_statistics_;
186 bool compilation_failed_;
187 Handle<Code> code_;
143 188
144 ZonePool::Scope graph_zone_scope_; 189 ZonePool::Scope graph_zone_scope_;
145 Zone* graph_zone_; 190 Zone* graph_zone_;
146 // All objects in the following group of fields are allocated in graph_zone_. 191 // All objects in the following group of fields are allocated in graph_zone_.
147 // They are all set to NULL when the graph_zone_ is destroyed. 192 // They are all set to NULL when the graph_zone_ is destroyed.
148 Graph* graph_; 193 Graph* graph_;
149 // TODO(dcarney): make this into a ZoneObject. 194 // TODO(dcarney): make this into a ZoneObject.
150 SmartPointer<SourcePositionTable> source_positions_; 195 SmartPointer<SourcePositionTable> source_positions_;
151 MachineOperatorBuilder* machine_; 196 MachineOperatorBuilder* machine_;
152 CommonOperatorBuilder* common_; 197 CommonOperatorBuilder* common_;
153 JSOperatorBuilder* javascript_; 198 JSOperatorBuilder* javascript_;
154 JSGraph* jsgraph_; 199 JSGraph* jsgraph_;
155 // TODO(dcarney): make this into a ZoneObject. 200 // TODO(dcarney): make this into a ZoneObject.
156 SmartPointer<Typer> typer_; 201 SmartPointer<Typer> typer_;
202 Node* context_node_;
157 Schedule* schedule_; 203 Schedule* schedule_;
158 204
159 // All objects in the following group of fields are allocated in 205 // All objects in the following group of fields are allocated in
160 // instruction_zone_. They are all set to NULL when the instruction_zone_ is 206 // instruction_zone_. They are all set to NULL when the instruction_zone_ is
161 // destroyed. 207 // destroyed.
162 ZonePool::Scope instruction_zone_scope_; 208 ZonePool::Scope instruction_zone_scope_;
163 Zone* instruction_zone_; 209 Zone* instruction_zone_;
210 InstructionSequence* sequence_;
211 Frame* frame_;
164 212
165 DISALLOW_COPY_AND_ASSIGN(PipelineData); 213 DISALLOW_COPY_AND_ASSIGN(PipelineData);
166 }; 214 };
167 215
168 216
169 static inline bool VerifyGraphs() { 217 static inline bool VerifyGraphs() {
170 #ifdef DEBUG 218 #ifdef DEBUG
171 return true; 219 return true;
172 #else 220 #else
173 return FLAG_turbo_verify; 221 return FLAG_turbo_verify;
174 #endif 222 #endif
175 } 223 }
176 224
177 225
178 struct TurboCfgFile : public std::ofstream { 226 struct TurboCfgFile : public std::ofstream {
179 explicit TurboCfgFile(Isolate* isolate) 227 explicit TurboCfgFile(Isolate* isolate)
180 : std::ofstream(isolate->GetTurboCfgFileName().c_str(), 228 : std::ofstream(isolate->GetTurboCfgFileName().c_str(),
181 std::ios_base::app) {} 229 std::ios_base::app) {}
182 }; 230 };
183 231
184 232
185 void Pipeline::VerifyAndPrintGraph( 233 static void TraceSchedule(Schedule* schedule) {
186 Graph* graph, const char* phase, bool untyped) { 234 if (!FLAG_trace_turbo) return;
187 if (FLAG_trace_turbo) { 235 OFStream os(stdout);
236 os << "-- Schedule --------------------------------------\n" << *schedule;
237 }
238
239
240 static SmartArrayPointer<char> GetDebugName(CompilationInfo* info) {
241 SmartArrayPointer<char> name;
242 if (info->IsStub()) {
243 if (info->code_stub() != NULL) {
244 CodeStub::Major major_key = info->code_stub()->MajorKey();
245 const char* major_name = CodeStub::MajorName(major_key, false);
246 size_t len = strlen(major_name);
247 name.Reset(new char[len]);
248 memcpy(name.get(), major_name, len);
249 }
250 } else {
251 AllowHandleDereference allow_deref;
252 name = info->function()->debug_name()->ToCString();
253 }
254 return name;
255 }
256
257
258 class AstGraphBuilderWithPositions : public AstGraphBuilder {
259 public:
260 explicit AstGraphBuilderWithPositions(Zone* local_zone, CompilationInfo* info,
261 JSGraph* jsgraph,
262 SourcePositionTable* source_positions)
263 : AstGraphBuilder(local_zone, info, jsgraph),
264 source_positions_(source_positions) {}
265
266 bool CreateGraph() {
267 SourcePositionTable::Scope pos(source_positions_,
268 SourcePosition::Unknown());
269 return AstGraphBuilder::CreateGraph();
270 }
271
272 #define DEF_VISIT(type) \
273 virtual void Visit##type(type* node) OVERRIDE { \
274 SourcePositionTable::Scope pos(source_positions_, \
275 SourcePosition(node->position())); \
276 AstGraphBuilder::Visit##type(node); \
277 }
278 AST_NODE_LIST(DEF_VISIT)
279 #undef DEF_VISIT
280
281 Node* GetFunctionContext() { return AstGraphBuilder::GetFunctionContext(); }
282
283 private:
284 SourcePositionTable* source_positions_;
285 };
286
287
288 class PipelineRunScope {
289 public:
290 PipelineRunScope(PipelineData* data, const char* phase_name)
291 : phase_scope_(
292 phase_name == nullptr ? nullptr : data->pipeline_statistics(),
293 phase_name),
294 zone_scope_(data->zone_pool()) {}
295
296 Zone* zone() { return zone_scope_.zone(); }
297
298 private:
299 PhaseScope phase_scope_;
300 ZonePool::Scope zone_scope_;
301 };
302
303
304 template <typename Phase>
305 void Pipeline::Run() {
306 PipelineRunScope scope(this->data_, Phase::phase_name());
307 Phase phase;
308 phase.Run(this->data_, scope.zone());
309 }
310
311
312 template <typename Phase, typename Arg0>
313 void Pipeline::Run(Arg0 arg_0) {
314 PipelineRunScope scope(this->data_, Phase::phase_name());
315 Phase phase;
316 phase.Run(this->data_, scope.zone(), arg_0);
317 }
318
319
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 {
330 static const char* phase_name() { return "graph builder"; }
331
332 void Run(PipelineData* data, Zone* temp_zone) {
333 AstGraphBuilderWithPositions graph_builder(
334 temp_zone, data->info(), data->jsgraph(), data->source_positions());
335 if (graph_builder.CreateGraph()) {
336 data->set_context_node(graph_builder.GetFunctionContext());
337 } else {
338 data->set_compilation_failed();
339 }
340 }
341 };
342
343
344 struct ContextSpecializerPhase {
345 static const char* phase_name() { return nullptr; }
346
347 void Run(PipelineData* data, Zone* temp_zone) {
348 SourcePositionTable::Scope pos(data->source_positions(),
349 SourcePosition::Unknown());
350 JSContextSpecializer spec(data->info(), data->jsgraph(),
351 data->context_node());
352 spec.SpecializeToContext();
353 }
354 };
355
356
357 struct InliningPhase {
358 static const char* phase_name() { return "inlining"; }
359
360 void Run(PipelineData* data, Zone* temp_zone) {
361 SourcePositionTable::Scope pos(data->source_positions(),
362 SourcePosition::Unknown());
363 JSInliner inliner(temp_zone, data->info(), data->jsgraph());
364 inliner.Inline();
365 }
366 };
367
368
369 struct TyperPhase {
370 static const char* phase_name() { return "typer"; }
371
372 void Run(PipelineData* data, Zone* temp_zone) { data->typer()->Run(); }
373 };
374
375
376 struct TypedLoweringPhase {
377 static const char* phase_name() { return "typed lowering"; }
378
379 void Run(PipelineData* data, Zone* temp_zone) {
380 SourcePositionTable::Scope pos(data->source_positions(),
381 SourcePosition::Unknown());
382 ValueNumberingReducer vn_reducer(data->graph_zone());
383 JSTypedLowering lowering(data->jsgraph());
384 SimplifiedOperatorReducer simple_reducer(data->jsgraph());
385 GraphReducer graph_reducer(data->graph());
386 graph_reducer.AddReducer(&vn_reducer);
387 graph_reducer.AddReducer(&lowering);
388 graph_reducer.AddReducer(&simple_reducer);
389 graph_reducer.ReduceGraph();
390 }
391 };
392
393
394 struct SimplifiedLoweringPhase {
395 static const char* phase_name() { return "simplified lowering"; }
396
397 void Run(PipelineData* data, Zone* temp_zone) {
398 SourcePositionTable::Scope pos(data->source_positions(),
399 SourcePosition::Unknown());
400 SimplifiedLowering lowering(data->jsgraph());
401 lowering.LowerAllNodes();
402 ValueNumberingReducer vn_reducer(data->graph_zone());
403 SimplifiedOperatorReducer simple_reducer(data->jsgraph());
404 GraphReducer graph_reducer(data->graph());
405 graph_reducer.AddReducer(&vn_reducer);
406 graph_reducer.AddReducer(&simple_reducer);
407 graph_reducer.ReduceGraph();
408 }
409 };
410
411
412 struct ChangeLoweringPhase {
413 static const char* phase_name() { return "change lowering"; }
414
415 void Run(PipelineData* data, Zone* temp_zone) {
416 SourcePositionTable::Scope pos(data->source_positions(),
417 SourcePosition::Unknown());
418 Linkage linkage(data->graph_zone(), data->info());
419 ValueNumberingReducer vn_reducer(data->graph_zone());
420 SimplifiedOperatorReducer simple_reducer(data->jsgraph());
421 ChangeLowering lowering(data->jsgraph(), &linkage);
422 MachineOperatorReducer mach_reducer(data->jsgraph());
423 GraphReducer graph_reducer(data->graph());
424 // TODO(titzer): Figure out if we should run all reducers at once here.
425 graph_reducer.AddReducer(&vn_reducer);
426 graph_reducer.AddReducer(&simple_reducer);
427 graph_reducer.AddReducer(&lowering);
428 graph_reducer.AddReducer(&mach_reducer);
429 graph_reducer.ReduceGraph();
430 }
431 };
432
433
434 struct ControlReductionPhase {
435 void Run(PipelineData* data, Zone* temp_zone) {
436 SourcePositionTable::Scope pos(data->source_positions(),
437 SourcePosition::Unknown());
438 ControlReducer::ReduceGraph(temp_zone, data->jsgraph(), data->common());
439 }
440 };
441
442
443 struct EarlyControlReductionPhase : ControlReductionPhase {
444 static const char* phase_name() { return "early control reduction"; }
445 };
446
447
448 struct LateControlReductionPhase : ControlReductionPhase {
449 static const char* phase_name() { return "late control reduction"; }
450 };
451
452
453 struct GenericLoweringPhase {
454 static const char* phase_name() { return "generic lowering"; }
455
456 void Run(PipelineData* data, Zone* temp_zone) {
457 SourcePositionTable::Scope pos(data->source_positions(),
458 SourcePosition::Unknown());
459 JSGenericLowering generic(data->info(), data->jsgraph());
460 SelectLowering select(data->jsgraph()->graph(), data->jsgraph()->common());
461 GraphReducer graph_reducer(data->graph());
462 graph_reducer.AddReducer(&generic);
463 graph_reducer.AddReducer(&select);
464 graph_reducer.ReduceGraph();
465 }
466 };
467
468
469 struct ComputeSchedulePhase {
470 static const char* phase_name() { return "scheduling"; }
471
472 void Run(PipelineData* data, Zone* temp_zone) {
473 Schedule* schedule = Scheduler::ComputeSchedule(temp_zone, data->graph());
474 TraceSchedule(schedule);
475 if (VerifyGraphs()) ScheduleVerifier::Run(schedule);
476 data->set_schedule(schedule);
477 }
478 };
479
480
481 struct InstructionSelectionPhase {
482 static const char* phase_name() { return "select instructions"; }
483
484 void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage) {
485 InstructionSelector selector(temp_zone, data->graph(), linkage,
486 data->sequence(), data->schedule(),
487 data->source_positions());
488 selector.SelectInstructions();
489 }
490 };
491
492
493 // TODO(dcarney): break this up.
494 struct RegisterAllocationPhase {
495 static const char* phase_name() { return nullptr; }
496
497 void Run(PipelineData* data, Zone* temp_zone) {
498 int node_count = data->sequence()->VirtualRegisterCount();
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 }
533 };
534
535
536 struct GenerateCodePhase {
537 static const char* phase_name() { return "generate code"; }
538
539 void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage,
540 CompilationInfo* info) {
541 CodeGenerator generator(data->frame(), linkage, data->sequence(), info);
542 data->set_code(generator.GenerateCode());
543 }
544 };
545
546
547 struct PrintGraphPhase {
548 static const char* phase_name() { return nullptr; }
549
550 void Run(PipelineData* data, Zone* temp_zone, const char* phase) {
551 CompilationInfo* info = data->info();
552 Graph* graph = data->graph();
188 char buffer[256]; 553 char buffer[256];
189 Vector<char> filename(buffer, sizeof(buffer)); 554 Vector<char> filename(buffer, sizeof(buffer));
190 SmartArrayPointer<char> functionname; 555 SmartArrayPointer<char> functionname;
191 if (!info_->shared_info().is_null()) { 556 if (!info->shared_info().is_null()) {
192 functionname = info_->shared_info()->DebugName()->ToCString(); 557 functionname = info->shared_info()->DebugName()->ToCString();
193 if (strlen(functionname.get()) > 0) { 558 if (strlen(functionname.get()) > 0) {
194 SNPrintF(filename, "turbo-%s-%s", functionname.get(), phase); 559 SNPrintF(filename, "turbo-%s-%s", functionname.get(), phase);
195 } else { 560 } else {
196 SNPrintF(filename, "turbo-%p-%s", static_cast<void*>(info_), phase); 561 SNPrintF(filename, "turbo-%p-%s", static_cast<void*>(info), phase);
197 } 562 }
198 } else { 563 } else {
199 SNPrintF(filename, "turbo-none-%s", phase); 564 SNPrintF(filename, "turbo-none-%s", phase);
200 } 565 }
201 std::replace(filename.start(), filename.start() + filename.length(), ' ', 566 std::replace(filename.start(), filename.start() + filename.length(), ' ',
202 '_'); 567 '_');
203 568
204 char dot_buffer[256]; 569 char dot_buffer[256];
205 Vector<char> dot_filename(dot_buffer, sizeof(dot_buffer)); 570 Vector<char> dot_filename(dot_buffer, sizeof(dot_buffer));
206 SNPrintF(dot_filename, "%s.dot", filename.start()); 571 SNPrintF(dot_filename, "%s.dot", filename.start());
207 FILE* dot_file = base::OS::FOpen(dot_filename.start(), "w+"); 572 FILE* dot_file = base::OS::FOpen(dot_filename.start(), "w+");
208 OFStream dot_of(dot_file); 573 OFStream dot_of(dot_file);
209 dot_of << AsDOT(*graph); 574 dot_of << AsDOT(*graph);
210 fclose(dot_file); 575 fclose(dot_file);
211 576
212 char json_buffer[256]; 577 char json_buffer[256];
213 Vector<char> json_filename(json_buffer, sizeof(json_buffer)); 578 Vector<char> json_filename(json_buffer, sizeof(json_buffer));
214 SNPrintF(json_filename, "%s.json", filename.start()); 579 SNPrintF(json_filename, "%s.json", filename.start());
215 FILE* json_file = base::OS::FOpen(json_filename.start(), "w+"); 580 FILE* json_file = base::OS::FOpen(json_filename.start(), "w+");
216 OFStream json_of(json_file); 581 OFStream json_of(json_file);
217 json_of << AsJSON(*graph); 582 json_of << AsJSON(*graph);
218 fclose(json_file); 583 fclose(json_file);
219 584
220 OFStream os(stdout); 585 OFStream os(stdout);
221 os << "-- " << phase << " graph printed to file " << filename.start() 586 os << "-- " << phase << " graph printed to file " << filename.start()
222 << "\n"; 587 << "\n";
223 } 588 }
589 };
590
591
592 struct VerifyGraphPhase {
593 static const char* phase_name() { return nullptr; }
594
595 void Run(PipelineData* data, Zone* temp_zone, const bool untyped) {
596 Verifier::Run(data->graph(), FLAG_turbo_types && !untyped
597 ? Verifier::TYPED
598 : Verifier::UNTYPED);
599 }
600 };
601
602
603 void Pipeline::RunPrintAndVerify(const char* phase, bool untyped) {
604 if (FLAG_trace_turbo) {
605 Run<PrintGraphPhase>(phase);
606 }
224 if (VerifyGraphs()) { 607 if (VerifyGraphs()) {
225 Verifier::Run(graph, 608 Run<VerifyGraphPhase>(untyped);
226 FLAG_turbo_types && !untyped ? Verifier::TYPED : Verifier::UNTYPED);
227 } 609 }
228 } 610 }
229 611
230 612
231 class AstGraphBuilderWithPositions : public AstGraphBuilder {
232 public:
233 explicit AstGraphBuilderWithPositions(Zone* local_zone, CompilationInfo* info,
234 JSGraph* jsgraph,
235 SourcePositionTable* source_positions)
236 : AstGraphBuilder(local_zone, info, jsgraph),
237 source_positions_(source_positions) {}
238
239 bool CreateGraph() {
240 SourcePositionTable::Scope pos(source_positions_,
241 SourcePosition::Unknown());
242 return AstGraphBuilder::CreateGraph();
243 }
244
245 #define DEF_VISIT(type) \
246 virtual void Visit##type(type* node) OVERRIDE { \
247 SourcePositionTable::Scope pos(source_positions_, \
248 SourcePosition(node->position())); \
249 AstGraphBuilder::Visit##type(node); \
250 }
251 AST_NODE_LIST(DEF_VISIT)
252 #undef DEF_VISIT
253
254 private:
255 SourcePositionTable* source_positions_;
256 };
257
258
259 static void TraceSchedule(Schedule* schedule) {
260 if (!FLAG_trace_turbo) return;
261 OFStream os(stdout);
262 os << "-- Schedule --------------------------------------\n" << *schedule;
263 }
264
265
266 static SmartArrayPointer<char> GetDebugName(CompilationInfo* info) {
267 SmartArrayPointer<char> name;
268 if (info->IsStub()) {
269 if (info->code_stub() != NULL) {
270 CodeStub::Major major_key = info->code_stub()->MajorKey();
271 const char* major_name = CodeStub::MajorName(major_key, false);
272 size_t len = strlen(major_name);
273 name.Reset(new char[len]);
274 memcpy(name.get(), major_name, len);
275 }
276 } else {
277 AllowHandleDereference allow_deref;
278 name = info->function()->debug_name()->ToCString();
279 }
280 return name;
281 }
282
283
284 Handle<Code> Pipeline::GenerateCode() { 613 Handle<Code> Pipeline::GenerateCode() {
285 // This list must be kept in sync with DONT_TURBOFAN_NODE in ast.cc. 614 // This list must be kept in sync with DONT_TURBOFAN_NODE in ast.cc.
286 if (info()->function()->dont_optimize_reason() == kTryCatchStatement || 615 if (info()->function()->dont_optimize_reason() == kTryCatchStatement ||
287 info()->function()->dont_optimize_reason() == kTryFinallyStatement || 616 info()->function()->dont_optimize_reason() == kTryFinallyStatement ||
288 // TODO(turbofan): Make ES6 for-of work and remove this bailout. 617 // TODO(turbofan): Make ES6 for-of work and remove this bailout.
289 info()->function()->dont_optimize_reason() == kForOfStatement || 618 info()->function()->dont_optimize_reason() == kForOfStatement ||
290 // TODO(turbofan): Make super work and remove this bailout. 619 // TODO(turbofan): Make super work and remove this bailout.
291 info()->function()->dont_optimize_reason() == kSuperReference || 620 info()->function()->dont_optimize_reason() == kSuperReference ||
292 // TODO(turbofan): Make class literals work and remove this bailout. 621 // TODO(turbofan): Make class literals work and remove this bailout.
293 info()->function()->dont_optimize_reason() == kClassLiteral || 622 info()->function()->dont_optimize_reason() == kClassLiteral ||
294 // TODO(turbofan): Make OSR work and remove this bailout. 623 // TODO(turbofan): Make OSR work and remove this bailout.
295 info()->is_osr()) { 624 info()->is_osr()) {
296 return Handle<Code>::null(); 625 return Handle<Code>::null();
297 } 626 }
298 627
299 ZonePool zone_pool(isolate()); 628 ZonePool zone_pool(isolate());
629 SmartPointer<PipelineStatistics> pipeline_statistics;
300 630
301 SmartPointer<PipelineStatistics> pipeline_statistics;
302 if (FLAG_turbo_stats) { 631 if (FLAG_turbo_stats) {
303 pipeline_statistics.Reset(new PipelineStatistics(info(), &zone_pool)); 632 pipeline_statistics.Reset(new PipelineStatistics(info(), &zone_pool));
304 pipeline_statistics->BeginPhaseKind("graph creation"); 633 pipeline_statistics->BeginPhaseKind("graph creation");
305 } 634 }
306 635
636 PipelineData data(info(), &zone_pool, pipeline_statistics.get());
637 this->data_ = &data;
638
307 if (FLAG_trace_turbo) { 639 if (FLAG_trace_turbo) {
308 OFStream os(stdout); 640 OFStream os(stdout);
309 os << "---------------------------------------------------\n" 641 os << "---------------------------------------------------\n"
310 << "Begin compiling method " << GetDebugName(info()).get() 642 << "Begin compiling method " << GetDebugName(info()).get()
311 << " using Turbofan" << std::endl; 643 << " using Turbofan" << std::endl;
312 TurboCfgFile tcf(isolate()); 644 TurboCfgFile tcf(isolate());
313 tcf << AsC1VCompilation(info()); 645 tcf << AsC1VCompilation(info());
314 } 646 }
315 647
316 // Initialize the graph and builders.
317 PipelineData data(info(), &zone_pool, pipeline_statistics.get());
318
319 data.source_positions()->AddDecorator(); 648 data.source_positions()->AddDecorator();
320 649
321 Node* context_node; 650 Run<GraphBuilderPhase>();
322 { 651 if (data.compilation_failed()) return Handle<Code>::null();
323 PhaseScope phase_scope(pipeline_statistics.get(), "graph builder"); 652 RunPrintAndVerify("Initial untyped", true);
324 ZonePool::Scope zone_scope(data.zone_pool());
325 AstGraphBuilderWithPositions graph_builder(
326 zone_scope.zone(), info(), data.jsgraph(), data.source_positions());
327 if (!graph_builder.CreateGraph()) return Handle<Code>::null();
328 context_node = graph_builder.GetFunctionContext();
329 }
330 653
331 VerifyAndPrintGraph(data.graph(), "Initial untyped", true); 654 Run<EarlyControlReductionPhase>();
332 655 RunPrintAndVerify("Early Control reduced", true);
333 {
334 PhaseScope phase_scope(pipeline_statistics.get(),
335 "early control reduction");
336 SourcePositionTable::Scope pos(data.source_positions(),
337 SourcePosition::Unknown());
338 ZonePool::Scope zone_scope(data.zone_pool());
339 ControlReducer::ReduceGraph(zone_scope.zone(), data.jsgraph(),
340 data.common());
341
342 VerifyAndPrintGraph(data.graph(), "Early Control reduced", true);
343 }
344 656
345 if (info()->is_context_specializing()) { 657 if (info()->is_context_specializing()) {
346 SourcePositionTable::Scope pos(data.source_positions(),
347 SourcePosition::Unknown());
348 // Specialize the code to the context as aggressively as possible. 658 // Specialize the code to the context as aggressively as possible.
349 JSContextSpecializer spec(info(), data.jsgraph(), context_node); 659 Run<ContextSpecializerPhase>();
350 spec.SpecializeToContext(); 660 RunPrintAndVerify("Context specialized", true);
351 VerifyAndPrintGraph(data.graph(), "Context specialized", true);
352 } 661 }
353 662
354 if (info()->is_inlining_enabled()) { 663 if (info()->is_inlining_enabled()) {
355 PhaseScope phase_scope(pipeline_statistics.get(), "inlining"); 664 Run<InliningPhase>();
356 SourcePositionTable::Scope pos(data.source_positions(), 665 RunPrintAndVerify("Inlined", true);
357 SourcePosition::Unknown());
358 ZonePool::Scope zone_scope(data.zone_pool());
359 JSInliner inliner(zone_scope.zone(), info(), data.jsgraph());
360 inliner.Inline();
361 VerifyAndPrintGraph(data.graph(), "Inlined", true);
362 } 666 }
363 667
364 // Print a replay of the initial graph.
365 if (FLAG_print_turbo_replay) { 668 if (FLAG_print_turbo_replay) {
669 // Print a replay of the initial graph.
366 GraphReplayPrinter::PrintReplay(data.graph()); 670 GraphReplayPrinter::PrintReplay(data.graph());
367 } 671 }
368 672
369 // Bailout here in case target architecture is not supported. 673 // Bailout here in case target architecture is not supported.
370 if (!SupportedTarget()) return Handle<Code>::null(); 674 if (!SupportedTarget()) return Handle<Code>::null();
371 675
372 if (info()->is_typing_enabled()) { 676 if (info()->is_typing_enabled()) {
373 { 677 // Type the graph.
374 // Type the graph. 678 Run<TyperPhase>();
375 PhaseScope phase_scope(pipeline_statistics.get(), "typer"); 679 RunPrintAndVerify("Typed");
376 data.typer()->Run();
377 VerifyAndPrintGraph(data.graph(), "Typed");
378 }
379 } 680 }
380 681
381 if (!pipeline_statistics.is_empty()) { 682 if (!pipeline_statistics.is_empty()) {
382 pipeline_statistics->BeginPhaseKind("lowering"); 683 data.pipeline_statistics()->BeginPhaseKind("lowering");
383 } 684 }
384 685
385 if (info()->is_typing_enabled()) { 686 if (info()->is_typing_enabled()) {
386 { 687 // Lower JSOperators where we can determine types.
387 // Lower JSOperators where we can determine types. 688 Run<TypedLoweringPhase>();
388 PhaseScope phase_scope(pipeline_statistics.get(), "typed lowering"); 689 RunPrintAndVerify("Lowered typed");
389 SourcePositionTable::Scope pos(data.source_positions(),
390 SourcePosition::Unknown());
391 ValueNumberingReducer vn_reducer(data.graph_zone());
392 JSTypedLowering lowering(data.jsgraph());
393 SimplifiedOperatorReducer simple_reducer(data.jsgraph());
394 GraphReducer graph_reducer(data.graph());
395 graph_reducer.AddReducer(&vn_reducer);
396 graph_reducer.AddReducer(&lowering);
397 graph_reducer.AddReducer(&simple_reducer);
398 graph_reducer.ReduceGraph();
399 690
400 VerifyAndPrintGraph(data.graph(), "Lowered typed"); 691 // Lower simplified operators and insert changes.
401 } 692 Run<SimplifiedLoweringPhase>();
402 { 693 RunPrintAndVerify("Lowered simplified");
403 // Lower simplified operators and insert changes.
404 PhaseScope phase_scope(pipeline_statistics.get(), "simplified lowering");
405 SourcePositionTable::Scope pos(data.source_positions(),
406 SourcePosition::Unknown());
407 SimplifiedLowering lowering(data.jsgraph());
408 lowering.LowerAllNodes();
409 ValueNumberingReducer vn_reducer(data.graph_zone());
410 SimplifiedOperatorReducer simple_reducer(data.jsgraph());
411 GraphReducer graph_reducer(data.graph());
412 graph_reducer.AddReducer(&vn_reducer);
413 graph_reducer.AddReducer(&simple_reducer);
414 graph_reducer.ReduceGraph();
415 694
416 VerifyAndPrintGraph(data.graph(), "Lowered simplified"); 695 // Lower changes that have been inserted before.
417 } 696 Run<ChangeLoweringPhase>();
418 { 697 // // TODO(jarin, rossberg): Remove UNTYPED once machine typing works.
419 // Lower changes that have been inserted before. 698 RunPrintAndVerify("Lowered changes", true);
420 PhaseScope phase_scope(pipeline_statistics.get(), "change lowering");
421 SourcePositionTable::Scope pos(data.source_positions(),
422 SourcePosition::Unknown());
423 Linkage linkage(data.graph_zone(), info());
424 ValueNumberingReducer vn_reducer(data.graph_zone());
425 SimplifiedOperatorReducer simple_reducer(data.jsgraph());
426 ChangeLowering lowering(data.jsgraph(), &linkage);
427 MachineOperatorReducer mach_reducer(data.jsgraph());
428 GraphReducer graph_reducer(data.graph());
429 // TODO(titzer): Figure out if we should run all reducers at once here.
430 graph_reducer.AddReducer(&vn_reducer);
431 graph_reducer.AddReducer(&simple_reducer);
432 graph_reducer.AddReducer(&lowering);
433 graph_reducer.AddReducer(&mach_reducer);
434 graph_reducer.ReduceGraph();
435 699
436 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. 700 Run<LateControlReductionPhase>();
437 VerifyAndPrintGraph(data.graph(), "Lowered changes", true); 701 RunPrintAndVerify("Late Control reduced");
438 }
439
440 {
441 PhaseScope phase_scope(pipeline_statistics.get(),
442 "late control reduction");
443 SourcePositionTable::Scope pos(data.source_positions(),
444 SourcePosition::Unknown());
445 ZonePool::Scope zone_scope(data.zone_pool());
446 ControlReducer::ReduceGraph(zone_scope.zone(), data.jsgraph(),
447 data.common());
448
449 VerifyAndPrintGraph(data.graph(), "Late Control reduced");
450 }
451 } 702 }
452 703
453 { 704 // Lower any remaining generic JSOperators.
454 // Lower any remaining generic JSOperators. 705 Run<GenericLoweringPhase>();
455 PhaseScope phase_scope(pipeline_statistics.get(), "generic lowering"); 706 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works.
456 SourcePositionTable::Scope pos(data.source_positions(), 707 RunPrintAndVerify("Lowered generic", true);
457 SourcePosition::Unknown());
458 JSGenericLowering generic(info(), data.jsgraph());
459 SelectLowering select(data.jsgraph()->graph(), data.jsgraph()->common());
460 GraphReducer graph_reducer(data.graph());
461 graph_reducer.AddReducer(&generic);
462 graph_reducer.AddReducer(&select);
463 graph_reducer.ReduceGraph();
464
465 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works.
466 VerifyAndPrintGraph(data.graph(), "Lowered generic", true);
467 }
468 708
469 if (!pipeline_statistics.is_empty()) { 709 if (!pipeline_statistics.is_empty()) {
470 pipeline_statistics->BeginPhaseKind("block building"); 710 data.pipeline_statistics()->BeginPhaseKind("block building");
471 } 711 }
472 712
473 data.source_positions()->RemoveDecorator(); 713 data.source_positions()->RemoveDecorator();
474 714
475 // Compute a schedule. 715 // Compute a schedule.
476 ComputeSchedule(&data); 716 Run<ComputeSchedulePhase>();
477 717
478 Handle<Code> code = Handle<Code>::null();
479 { 718 {
480 // Generate optimized code. 719 // Generate optimized code.
481 Linkage linkage(data.instruction_zone(), info()); 720 Linkage linkage(data.instruction_zone(), info());
482 code = GenerateCode(&linkage, &data); 721 GenerateCode(&linkage);
483 info()->SetCode(code);
484 } 722 }
723 Handle<Code> code = data.code();
724 info()->SetCode(code);
485 725
486 // Print optimized code. 726 // Print optimized code.
487 v8::internal::CodeGenerator::PrintCode(code, info()); 727 v8::internal::CodeGenerator::PrintCode(code, info());
488 728
489 if (FLAG_trace_turbo) { 729 if (FLAG_trace_turbo) {
490 OFStream os(stdout); 730 OFStream os(stdout);
491 os << "--------------------------------------------------\n" 731 os << "--------------------------------------------------\n"
492 << "Finished compiling method " << GetDebugName(info()).get() 732 << "Finished compiling method " << GetDebugName(info()).get()
493 << " using Turbofan" << std::endl; 733 << " using Turbofan" << std::endl;
494 } 734 }
495 735
496 return code; 736 return code;
497 } 737 }
498 738
499 739
500 void Pipeline::ComputeSchedule(PipelineData* data) {
501 PhaseScope phase_scope(data->pipeline_statistics(), "scheduling");
502 ZonePool::Scope zone_scope(data->zone_pool());
503 Schedule* schedule =
504 Scheduler::ComputeSchedule(zone_scope.zone(), data->graph());
505 TraceSchedule(schedule);
506 if (VerifyGraphs()) ScheduleVerifier::Run(schedule);
507 data->set_schedule(schedule);
508 }
509
510
511 Handle<Code> Pipeline::GenerateCodeForMachineGraph(Linkage* linkage, 740 Handle<Code> Pipeline::GenerateCodeForMachineGraph(Linkage* linkage,
512 Graph* graph, 741 Graph* graph,
513 Schedule* schedule) { 742 Schedule* schedule) {
514 ZonePool zone_pool(isolate()); 743 ZonePool zone_pool(isolate());
515 CHECK(SupportedBackend()); 744 CHECK(SupportedBackend());
516 PipelineData data(graph, schedule, &zone_pool); 745 PipelineData data(graph, schedule, &zone_pool);
746 this->data_ = &data;
517 if (schedule == NULL) { 747 if (schedule == NULL) {
518 // TODO(rossberg): Should this really be untyped? 748 // TODO(rossberg): Should this really be untyped?
519 VerifyAndPrintGraph(graph, "Machine", true); 749 RunPrintAndVerify("Machine", true);
520 ComputeSchedule(&data); 750 Run<ComputeSchedulePhase>();
521 } else { 751 } else {
522 TraceSchedule(schedule); 752 TraceSchedule(schedule);
523 } 753 }
524 754
525 Handle<Code> code = GenerateCode(linkage, &data); 755 GenerateCode(linkage);
756 Handle<Code> code = data.code();
757
526 #if ENABLE_DISASSEMBLER 758 #if ENABLE_DISASSEMBLER
527 if (!code.is_null() && FLAG_print_opt_code) { 759 if (!code.is_null() && FLAG_print_opt_code) {
528 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer()); 760 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer());
529 OFStream os(tracing_scope.file()); 761 OFStream os(tracing_scope.file());
530 code->Disassemble("test code", os); 762 code->Disassemble("test code", os);
531 } 763 }
532 #endif 764 #endif
533 return code; 765 return code;
534 } 766 }
535 767
536 768
537 Handle<Code> Pipeline::GenerateCode(Linkage* linkage, PipelineData* data) { 769 void Pipeline::GenerateCode(Linkage* linkage) {
770 PipelineData* data = this->data_;
771
538 DCHECK_NOT_NULL(linkage); 772 DCHECK_NOT_NULL(linkage);
539 DCHECK_NOT_NULL(data->graph()); 773 DCHECK_NOT_NULL(data->graph());
540 DCHECK_NOT_NULL(data->schedule()); 774 DCHECK_NOT_NULL(data->schedule());
541 CHECK(SupportedBackend()); 775 CHECK(SupportedBackend());
542 776
543 BasicBlockProfiler::Data* profiler_data = NULL; 777 BasicBlockProfiler::Data* profiler_data = NULL;
544 if (FLAG_turbo_profiling) { 778 if (FLAG_turbo_profiling) {
545 profiler_data = BasicBlockInstrumentor::Instrument(info(), data->graph(), 779 profiler_data = BasicBlockInstrumentor::Instrument(info(), data->graph(),
546 data->schedule()); 780 data->schedule());
547 } 781 }
548 782
549 InstructionBlocks* instruction_blocks = 783 InstructionBlocks* instruction_blocks =
550 InstructionSequence::InstructionBlocksFor(data->instruction_zone(), 784 InstructionSequence::InstructionBlocksFor(data->instruction_zone(),
551 data->schedule()); 785 data->schedule());
552 InstructionSequence sequence(data->instruction_zone(), instruction_blocks); 786 data->set_sequence(new (data->instruction_zone()) InstructionSequence(
787 data->instruction_zone(), instruction_blocks));
553 788
554 // Select and schedule instructions covering the scheduled graph. 789 // Select and schedule instructions covering the scheduled graph.
555 { 790 Run<InstructionSelectionPhase>(linkage);
556 PhaseScope phase_scope(data->pipeline_statistics(), "select instructions");
557 ZonePool::Scope zone_scope(data->zone_pool());
558 InstructionSelector selector(zone_scope.zone(), data->graph(), linkage,
559 &sequence, data->schedule(),
560 data->source_positions());
561 selector.SelectInstructions();
562 }
563 791
564 if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) { 792 if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) {
565 TurboCfgFile tcf(isolate()); 793 TurboCfgFile tcf(isolate());
566 tcf << AsC1V("CodeGen", data->schedule(), data->source_positions(), 794 tcf << AsC1V("CodeGen", data->schedule(), data->source_positions(),
567 &sequence); 795 data->sequence());
568 } 796 }
569 797
570 data->DeleteGraphZone(); 798 data->DeleteGraphZone();
571 799
572 if (data->pipeline_statistics() != NULL) { 800 if (data->pipeline_statistics() != NULL) {
573 data->pipeline_statistics()->BeginPhaseKind("register allocation"); 801 data->pipeline_statistics()->BeginPhaseKind("register allocation");
574 } 802 }
575 803
576 #ifdef DEBUG 804 #ifdef DEBUG
577 // Don't track usage for this zone in compiler stats. 805 // Don't track usage for this zone in compiler stats.
578 Zone verifier_zone(info()->isolate()); 806 Zone verifier_zone(info()->isolate());
579 RegisterAllocatorVerifier verifier( 807 RegisterAllocatorVerifier verifier(
580 &verifier_zone, RegisterConfiguration::ArchDefault(), &sequence); 808 &verifier_zone, RegisterConfiguration::ArchDefault(), data->sequence());
581 #endif 809 #endif
582 810
583 // Allocate registers. 811 // Allocate registers.
584 Frame frame; 812 data->set_frame(new (data->instruction_zone()) Frame);
585 { 813 Run<RegisterAllocationPhase>();
586 int node_count = sequence.VirtualRegisterCount(); 814 if (data->compilation_failed()) {
587 if (node_count > UnallocatedOperand::kMaxVirtualRegisters) { 815 info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc);
588 info()->AbortOptimization(kNotEnoughVirtualRegistersForValues); 816 return;
589 return Handle<Code>::null();
590 }
591 ZonePool::Scope zone_scope(data->zone_pool());
592
593 SmartArrayPointer<char> debug_name;
594 #ifdef DEBUG
595 debug_name = GetDebugName(info());
596 #endif
597
598 RegisterAllocator allocator(RegisterConfiguration::ArchDefault(),
599 zone_scope.zone(), &frame, &sequence,
600 debug_name.get());
601 if (!allocator.Allocate(data->pipeline_statistics())) {
602 info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc);
603 return Handle<Code>::null();
604 }
605 if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) {
606 TurboCfgFile tcf(isolate());
607 tcf << AsC1VAllocator("CodeGen", &allocator);
608 }
609 }
610
611 if (FLAG_trace_turbo) {
612 OFStream os(stdout);
613 PrintableInstructionSequence printable = {
614 RegisterConfiguration::ArchDefault(), &sequence};
615 os << "----- Instruction sequence after register allocation -----\n"
616 << printable;
617 } 817 }
618 818
619 #ifdef DEBUG 819 #ifdef DEBUG
620 verifier.VerifyAssignment(); 820 verifier.VerifyAssignment();
621 verifier.VerifyGapMoves(); 821 verifier.VerifyGapMoves();
622 #endif 822 #endif
623 823
624 if (data->pipeline_statistics() != NULL) { 824 if (data->pipeline_statistics() != NULL) {
625 data->pipeline_statistics()->BeginPhaseKind("code generation"); 825 data->pipeline_statistics()->BeginPhaseKind("code generation");
626 } 826 }
627 827
628 // Generate native sequence. 828 // Generate native sequence.
629 Handle<Code> code; 829 Run<GenerateCodePhase>(linkage, info());
630 { 830
631 PhaseScope phase_scope(data->pipeline_statistics(), "generate code");
632 CodeGenerator generator(&frame, linkage, &sequence, info());
633 code = generator.GenerateCode();
634 }
635 if (profiler_data != NULL) { 831 if (profiler_data != NULL) {
636 #if ENABLE_DISASSEMBLER 832 #if ENABLE_DISASSEMBLER
637 std::ostringstream os; 833 std::ostringstream os;
638 code->Disassemble(NULL, os); 834 data->code()->Disassemble(NULL, os);
639 profiler_data->SetCode(&os); 835 profiler_data->SetCode(&os);
640 #endif 836 #endif
641 } 837 }
642 return code;
643 } 838 }
644 839
645 840
646 void Pipeline::SetUp() { 841 void Pipeline::SetUp() {
647 InstructionOperand::SetUpCaches(); 842 InstructionOperand::SetUpCaches();
648 } 843 }
649 844
650 845
651 void Pipeline::TearDown() { 846 void Pipeline::TearDown() {
652 InstructionOperand::TearDownCaches(); 847 InstructionOperand::TearDownCaches();
653 } 848 }
654 849
655 } // namespace compiler 850 } // namespace compiler
656 } // namespace internal 851 } // namespace internal
657 } // namespace v8 852 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/pipeline.h ('k') | test/cctest/compiler/test-codegen-deopt.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698