blob: 4d6aacd78a882eb888ae68409e06f485c818e0ba [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
3// found in the LICENSE file.
4
5#include "src/compiler/pipeline.h"
6
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007#include <fstream> // NOLINT(readability/streams)
8#include <sstream>
9
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010#include "src/base/adapters.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000011#include "src/base/platform/elapsed-timer.h"
12#include "src/compiler/ast-graph-builder.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040013#include "src/compiler/ast-loop-assignment-analyzer.h"
14#include "src/compiler/basic-block-instrumentor.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000015#include "src/compiler/branch-elimination.h"
16#include "src/compiler/bytecode-graph-builder.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000017#include "src/compiler/change-lowering.h"
18#include "src/compiler/code-generator.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040019#include "src/compiler/common-operator-reducer.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000020#include "src/compiler/control-flow-optimizer.h"
21#include "src/compiler/dead-code-elimination.h"
22#include "src/compiler/escape-analysis.h"
23#include "src/compiler/escape-analysis-reducer.h"
24#include "src/compiler/frame-elider.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000025#include "src/compiler/graph-replay.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000026#include "src/compiler/graph-trimmer.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000027#include "src/compiler/graph-visualizer.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000028#include "src/compiler/greedy-allocator.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000029#include "src/compiler/instruction.h"
30#include "src/compiler/instruction-selector.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040031#include "src/compiler/js-builtin-reducer.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000032#include "src/compiler/js-call-reducer.h"
33#include "src/compiler/js-context-relaxation.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000034#include "src/compiler/js-context-specialization.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000035#include "src/compiler/js-frame-specialization.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000036#include "src/compiler/js-generic-lowering.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000037#include "src/compiler/js-global-object-specialization.h"
38#include "src/compiler/js-inlining-heuristic.h"
39#include "src/compiler/js-intrinsic-lowering.h"
40#include "src/compiler/js-native-context-specialization.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000041#include "src/compiler/js-typed-lowering.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040042#include "src/compiler/jump-threading.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000043#include "src/compiler/live-range-separator.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040044#include "src/compiler/load-elimination.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000045#include "src/compiler/loop-analysis.h"
46#include "src/compiler/loop-peeling.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000047#include "src/compiler/machine-operator-reducer.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040048#include "src/compiler/move-optimizer.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000049#include "src/compiler/osr.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040050#include "src/compiler/pipeline-statistics.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000051#include "src/compiler/register-allocator.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040052#include "src/compiler/register-allocator-verifier.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000053#include "src/compiler/schedule.h"
54#include "src/compiler/scheduler.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040055#include "src/compiler/select-lowering.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000056#include "src/compiler/simplified-lowering.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000057#include "src/compiler/simplified-operator.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000058#include "src/compiler/simplified-operator-reducer.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000059#include "src/compiler/tail-call-optimization.h"
60#include "src/compiler/type-hint-analyzer.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000061#include "src/compiler/typer.h"
62#include "src/compiler/value-numbering-reducer.h"
63#include "src/compiler/verifier.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040064#include "src/compiler/zone-pool.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000065#include "src/ostreams.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000066#include "src/register-configuration.h"
67#include "src/type-info.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000068#include "src/utils.h"
69
70namespace v8 {
71namespace internal {
72namespace compiler {
73
Emily Bernierd0a1eb72015-03-24 16:35:39 -040074class PipelineData {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000075 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000076 // For main entry point.
77 PipelineData(ZonePool* zone_pool, CompilationInfo* info,
78 PipelineStatistics* pipeline_statistics)
79 : isolate_(info->isolate()),
80 info_(info),
81 outer_zone_(info_->zone()),
82 zone_pool_(zone_pool),
83 pipeline_statistics_(pipeline_statistics),
84 compilation_failed_(false),
85 code_(Handle<Code>::null()),
86 graph_zone_scope_(zone_pool_),
87 graph_zone_(graph_zone_scope_.zone()),
88 graph_(nullptr),
89 loop_assignment_(nullptr),
90 simplified_(nullptr),
91 machine_(nullptr),
92 common_(nullptr),
93 javascript_(nullptr),
94 jsgraph_(nullptr),
95 schedule_(nullptr),
96 instruction_zone_scope_(zone_pool_),
97 instruction_zone_(instruction_zone_scope_.zone()),
98 sequence_(nullptr),
99 frame_(nullptr),
100 register_allocation_zone_scope_(zone_pool_),
101 register_allocation_zone_(register_allocation_zone_scope_.zone()),
102 register_allocation_data_(nullptr) {
103 PhaseScope scope(pipeline_statistics, "init pipeline data");
104 graph_ = new (graph_zone_) Graph(graph_zone_);
105 source_positions_.Reset(new SourcePositionTable(graph_));
106 simplified_ = new (graph_zone_) SimplifiedOperatorBuilder(graph_zone_);
107 machine_ = new (graph_zone_) MachineOperatorBuilder(
108 graph_zone_, MachineType::PointerRepresentation(),
109 InstructionSelector::SupportedMachineOperatorFlags());
110 common_ = new (graph_zone_) CommonOperatorBuilder(graph_zone_);
111 javascript_ = new (graph_zone_) JSOperatorBuilder(graph_zone_);
112 jsgraph_ = new (graph_zone_)
113 JSGraph(isolate_, graph_, common_, javascript_, simplified_, machine_);
114 }
115
116 // For machine graph testing entry point.
117 PipelineData(ZonePool* zone_pool, CompilationInfo* info, Graph* graph,
118 Schedule* schedule)
119 : isolate_(info->isolate()),
120 info_(info),
121 outer_zone_(nullptr),
122 zone_pool_(zone_pool),
123 pipeline_statistics_(nullptr),
124 compilation_failed_(false),
125 code_(Handle<Code>::null()),
126 graph_zone_scope_(zone_pool_),
127 graph_zone_(nullptr),
128 graph_(graph),
129 source_positions_(new SourcePositionTable(graph_)),
130 loop_assignment_(nullptr),
131 simplified_(nullptr),
132 machine_(nullptr),
133 common_(nullptr),
134 javascript_(nullptr),
135 jsgraph_(nullptr),
136 schedule_(schedule),
137 instruction_zone_scope_(zone_pool_),
138 instruction_zone_(instruction_zone_scope_.zone()),
139 sequence_(nullptr),
140 frame_(nullptr),
141 register_allocation_zone_scope_(zone_pool_),
142 register_allocation_zone_(register_allocation_zone_scope_.zone()),
143 register_allocation_data_(nullptr) {}
144
145 // For register allocation testing entry point.
146 PipelineData(ZonePool* zone_pool, CompilationInfo* info,
147 InstructionSequence* sequence)
148 : isolate_(info->isolate()),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400149 info_(info),
150 outer_zone_(nullptr),
151 zone_pool_(zone_pool),
152 pipeline_statistics_(nullptr),
153 compilation_failed_(false),
154 code_(Handle<Code>::null()),
155 graph_zone_scope_(zone_pool_),
156 graph_zone_(nullptr),
157 graph_(nullptr),
158 loop_assignment_(nullptr),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000159 simplified_(nullptr),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400160 machine_(nullptr),
161 common_(nullptr),
162 javascript_(nullptr),
163 jsgraph_(nullptr),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400164 schedule_(nullptr),
165 instruction_zone_scope_(zone_pool_),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000166 instruction_zone_(sequence->zone()),
167 sequence_(sequence),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400168 frame_(nullptr),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000169 register_allocation_zone_scope_(zone_pool_),
170 register_allocation_zone_(register_allocation_zone_scope_.zone()),
171 register_allocation_data_(nullptr) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000172
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400173 ~PipelineData() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000174 DeleteRegisterAllocationZone();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400175 DeleteInstructionZone();
176 DeleteGraphZone();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000177 }
178
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400179 Isolate* isolate() const { return isolate_; }
180 CompilationInfo* info() const { return info_; }
181 ZonePool* zone_pool() const { return zone_pool_; }
182 PipelineStatistics* pipeline_statistics() { return pipeline_statistics_; }
183 bool compilation_failed() const { return compilation_failed_; }
184 void set_compilation_failed() { compilation_failed_ = true; }
185 Handle<Code> code() { return code_; }
186 void set_code(Handle<Code> code) {
187 DCHECK(code_.is_null());
188 code_ = code;
189 }
190
191 // RawMachineAssembler generally produces graphs which cannot be verified.
192 bool MayHaveUnverifiableGraph() const { return outer_zone_ == nullptr; }
193
194 Zone* graph_zone() const { return graph_zone_; }
195 Graph* graph() const { return graph_; }
196 SourcePositionTable* source_positions() const {
197 return source_positions_.get();
198 }
199 MachineOperatorBuilder* machine() const { return machine_; }
200 CommonOperatorBuilder* common() const { return common_; }
201 JSOperatorBuilder* javascript() const { return javascript_; }
202 JSGraph* jsgraph() const { return jsgraph_; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000203 MaybeHandle<Context> native_context() const {
204 if (info()->is_native_context_specializing()) {
205 return handle(info()->native_context(), isolate());
206 }
207 return MaybeHandle<Context>();
208 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400209
210 LoopAssignmentAnalysis* loop_assignment() const { return loop_assignment_; }
211 void set_loop_assignment(LoopAssignmentAnalysis* loop_assignment) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000212 DCHECK(!loop_assignment_);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400213 loop_assignment_ = loop_assignment;
214 }
215
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000216 TypeHintAnalysis* type_hint_analysis() const { return type_hint_analysis_; }
217 void set_type_hint_analysis(TypeHintAnalysis* type_hint_analysis) {
218 DCHECK_NULL(type_hint_analysis_);
219 type_hint_analysis_ = type_hint_analysis;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400220 }
221
222 Schedule* schedule() const { return schedule_; }
223 void set_schedule(Schedule* schedule) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000224 DCHECK(!schedule_);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400225 schedule_ = schedule;
226 }
227
228 Zone* instruction_zone() const { return instruction_zone_; }
229 InstructionSequence* sequence() const { return sequence_; }
230 Frame* frame() const { return frame_; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000231
232 Zone* register_allocation_zone() const { return register_allocation_zone_; }
233 RegisterAllocationData* register_allocation_data() const {
234 return register_allocation_data_;
235 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400236
237 void DeleteGraphZone() {
238 // Destroy objects with destructors first.
239 source_positions_.Reset(nullptr);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400240 if (graph_zone_ == nullptr) return;
241 // Destroy zone and clear pointers.
242 graph_zone_scope_.Destroy();
243 graph_zone_ = nullptr;
244 graph_ = nullptr;
245 loop_assignment_ = nullptr;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000246 type_hint_analysis_ = nullptr;
247 simplified_ = nullptr;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400248 machine_ = nullptr;
249 common_ = nullptr;
250 javascript_ = nullptr;
251 jsgraph_ = nullptr;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400252 schedule_ = nullptr;
253 }
254
255 void DeleteInstructionZone() {
256 if (instruction_zone_ == nullptr) return;
257 instruction_zone_scope_.Destroy();
258 instruction_zone_ = nullptr;
259 sequence_ = nullptr;
260 frame_ = nullptr;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000261 }
262
263 void DeleteRegisterAllocationZone() {
264 if (register_allocation_zone_ == nullptr) return;
265 register_allocation_zone_scope_.Destroy();
266 register_allocation_zone_ = nullptr;
267 register_allocation_data_ = nullptr;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400268 }
269
270 void InitializeInstructionSequence() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000271 DCHECK(sequence_ == nullptr);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400272 InstructionBlocks* instruction_blocks =
273 InstructionSequence::InstructionBlocksFor(instruction_zone(),
274 schedule());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000275 sequence_ = new (instruction_zone()) InstructionSequence(
276 info()->isolate(), instruction_zone(), instruction_blocks);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400277 }
278
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000279 void InitializeRegisterAllocationData(const RegisterConfiguration* config,
280 CallDescriptor* descriptor,
281 const char* debug_name) {
282 DCHECK(frame_ == nullptr);
283 DCHECK(register_allocation_data_ == nullptr);
284 int fixed_frame_size = 0;
285 if (descriptor != nullptr) {
286 fixed_frame_size = (descriptor->IsCFunctionCall())
287 ? StandardFrameConstants::kFixedSlotCountAboveFp +
288 StandardFrameConstants::kCPSlotCount
289 : StandardFrameConstants::kFixedSlotCount;
290 }
291 frame_ = new (instruction_zone()) Frame(fixed_frame_size, descriptor);
292 register_allocation_data_ = new (register_allocation_zone())
293 RegisterAllocationData(config, register_allocation_zone(), frame(),
294 sequence(), debug_name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000295 }
296
297 private:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400298 Isolate* isolate_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000299 CompilationInfo* info_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400300 Zone* outer_zone_;
301 ZonePool* const zone_pool_;
302 PipelineStatistics* pipeline_statistics_;
303 bool compilation_failed_;
304 Handle<Code> code_;
305
306 // All objects in the following group of fields are allocated in graph_zone_.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000307 // They are all set to nullptr when the graph_zone_ is destroyed.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400308 ZonePool::Scope graph_zone_scope_;
309 Zone* graph_zone_;
310 Graph* graph_;
311 // TODO(dcarney): make this into a ZoneObject.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000312 base::SmartPointer<SourcePositionTable> source_positions_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400313 LoopAssignmentAnalysis* loop_assignment_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000314 TypeHintAnalysis* type_hint_analysis_ = nullptr;
315 SimplifiedOperatorBuilder* simplified_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400316 MachineOperatorBuilder* machine_;
317 CommonOperatorBuilder* common_;
318 JSOperatorBuilder* javascript_;
319 JSGraph* jsgraph_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400320 Schedule* schedule_;
321
322 // All objects in the following group of fields are allocated in
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000323 // instruction_zone_. They are all set to nullptr when the instruction_zone_
324 // is
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400325 // destroyed.
326 ZonePool::Scope instruction_zone_scope_;
327 Zone* instruction_zone_;
328 InstructionSequence* sequence_;
329 Frame* frame_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000330
331 // All objects in the following group of fields are allocated in
332 // register_allocation_zone_. They are all set to nullptr when the zone is
333 // destroyed.
334 ZonePool::Scope register_allocation_zone_scope_;
335 Zone* register_allocation_zone_;
336 RegisterAllocationData* register_allocation_data_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400337
338 DISALLOW_COPY_AND_ASSIGN(PipelineData);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000339};
340
341
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000342namespace {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000343
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400344struct TurboCfgFile : public std::ofstream {
345 explicit TurboCfgFile(Isolate* isolate)
346 : std::ofstream(isolate->GetTurboCfgFileName().c_str(),
347 std::ios_base::app) {}
348};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000349
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400350
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000351void TraceSchedule(CompilationInfo* info, Schedule* schedule) {
352 if (FLAG_trace_turbo) {
353 FILE* json_file = OpenVisualizerLogFile(info, nullptr, "json", "a+");
354 if (json_file != nullptr) {
355 OFStream json_of(json_file);
356 json_of << "{\"name\":\"Schedule\",\"type\":\"schedule\",\"data\":\"";
357 std::stringstream schedule_stream;
358 schedule_stream << *schedule;
359 std::string schedule_string(schedule_stream.str());
360 for (const auto& c : schedule_string) {
361 json_of << AsEscapedUC16ForJSON(c);
362 }
363 json_of << "\"},\n";
364 fclose(json_file);
365 }
366 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400367 if (!FLAG_trace_turbo_graph && !FLAG_trace_turbo_scheduler) return;
368 OFStream os(stdout);
369 os << "-- Schedule --------------------------------------\n" << *schedule;
370}
371
372
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000373class AstGraphBuilderWithPositions final : public AstGraphBuilder {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000374 public:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400375 AstGraphBuilderWithPositions(Zone* local_zone, CompilationInfo* info,
376 JSGraph* jsgraph,
377 LoopAssignmentAnalysis* loop_assignment,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000378 TypeHintAnalysis* type_hint_analysis,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400379 SourcePositionTable* source_positions)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000380 : AstGraphBuilder(local_zone, info, jsgraph, loop_assignment,
381 type_hint_analysis),
382 source_positions_(source_positions),
383 start_position_(info->shared_info()->start_position()) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000384
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000385 bool CreateGraph(bool stack_check) {
386 SourcePositionTable::Scope pos_scope(source_positions_, start_position_);
387 return AstGraphBuilder::CreateGraph(stack_check);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000388 }
389
390#define DEF_VISIT(type) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000391 void Visit##type(type* node) override { \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000392 SourcePositionTable::Scope pos(source_positions_, \
393 SourcePosition(node->position())); \
394 AstGraphBuilder::Visit##type(node); \
395 }
396 AST_NODE_LIST(DEF_VISIT)
397#undef DEF_VISIT
398
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000399 private:
400 SourcePositionTable* const source_positions_;
401 SourcePosition const start_position_;
402};
403
404
405class SourcePositionWrapper final : public Reducer {
406 public:
407 SourcePositionWrapper(Reducer* reducer, SourcePositionTable* table)
408 : reducer_(reducer), table_(table) {}
409 ~SourcePositionWrapper() final {}
410
411 Reduction Reduce(Node* node) final {
412 SourcePosition const pos = table_->GetSourcePosition(node);
413 SourcePositionTable::Scope position(table_, pos);
414 return reducer_->Reduce(node);
415 }
416
417 void Finalize() final { reducer_->Finalize(); }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400418
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000419 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000420 Reducer* const reducer_;
421 SourcePositionTable* const table_;
422
423 DISALLOW_COPY_AND_ASSIGN(SourcePositionWrapper);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000424};
425
426
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000427class JSGraphReducer final : public GraphReducer {
428 public:
429 JSGraphReducer(JSGraph* jsgraph, Zone* zone)
430 : GraphReducer(zone, jsgraph->graph(), jsgraph->Dead()) {}
431 ~JSGraphReducer() final {}
432};
433
434
435void AddReducer(PipelineData* data, GraphReducer* graph_reducer,
436 Reducer* reducer) {
437 if (data->info()->is_source_positions_enabled()) {
438 void* const buffer = data->graph_zone()->New(sizeof(SourcePositionWrapper));
439 SourcePositionWrapper* const wrapper =
440 new (buffer) SourcePositionWrapper(reducer, data->source_positions());
441 graph_reducer->AddReducer(wrapper);
442 } else {
443 graph_reducer->AddReducer(reducer);
444 }
445}
446
447
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400448class PipelineRunScope {
449 public:
450 PipelineRunScope(PipelineData* data, const char* phase_name)
451 : phase_scope_(
452 phase_name == nullptr ? nullptr : data->pipeline_statistics(),
453 phase_name),
454 zone_scope_(data->zone_pool()) {}
455
456 Zone* zone() { return zone_scope_.zone(); }
457
458 private:
459 PhaseScope phase_scope_;
460 ZonePool::Scope zone_scope_;
461};
462
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000463} // namespace
464
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400465
466template <typename Phase>
467void Pipeline::Run() {
468 PipelineRunScope scope(this->data_, Phase::phase_name());
469 Phase phase;
470 phase.Run(this->data_, scope.zone());
471}
472
473
474template <typename Phase, typename Arg0>
475void Pipeline::Run(Arg0 arg_0) {
476 PipelineRunScope scope(this->data_, Phase::phase_name());
477 Phase phase;
478 phase.Run(this->data_, scope.zone(), arg_0);
479}
480
481
482struct LoopAssignmentAnalysisPhase {
483 static const char* phase_name() { return "loop assignment analysis"; }
484
485 void Run(PipelineData* data, Zone* temp_zone) {
486 AstLoopAssignmentAnalyzer analyzer(data->graph_zone(), data->info());
487 LoopAssignmentAnalysis* loop_assignment = analyzer.Analyze();
488 data->set_loop_assignment(loop_assignment);
489 }
490};
491
492
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000493struct TypeHintAnalysisPhase {
494 static const char* phase_name() { return "type hint analysis"; }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400495
496 void Run(PipelineData* data, Zone* temp_zone) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000497 TypeHintAnalyzer analyzer(data->graph_zone());
498 Handle<Code> code(data->info()->shared_info()->code(), data->isolate());
499 TypeHintAnalysis* type_hint_analysis = analyzer.Analyze(code);
500 data->set_type_hint_analysis(type_hint_analysis);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400501 }
502};
503
504
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000505struct GraphBuilderPhase {
506 static const char* phase_name() { return "graph builder"; }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400507
508 void Run(PipelineData* data, Zone* temp_zone) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000509 bool stack_check = !data->info()->IsStub();
510 bool succeeded = false;
511
512 if (data->info()->shared_info()->HasBytecodeArray()) {
513 BytecodeGraphBuilder graph_builder(temp_zone, data->info(),
514 data->jsgraph());
515 succeeded = graph_builder.CreateGraph(stack_check);
516 } else {
517 AstGraphBuilderWithPositions graph_builder(
518 temp_zone, data->info(), data->jsgraph(), data->loop_assignment(),
519 data->type_hint_analysis(), data->source_positions());
520 succeeded = graph_builder.CreateGraph(stack_check);
521 }
522
523 if (!succeeded) {
524 data->set_compilation_failed();
525 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400526 }
527};
528
529
530struct InliningPhase {
531 static const char* phase_name() { return "inlining"; }
532
533 void Run(PipelineData* data, Zone* temp_zone) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000534 JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
535 DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
536 data->common());
537 CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
538 data->common(), data->machine());
539 JSCallReducer call_reducer(data->jsgraph(),
540 data->info()->is_deoptimization_enabled()
541 ? JSCallReducer::kDeoptimizationEnabled
542 : JSCallReducer::kNoFlags,
543 data->native_context());
544 JSContextSpecialization context_specialization(
545 &graph_reducer, data->jsgraph(),
546 data->info()->is_function_context_specializing()
547 ? data->info()->context()
548 : MaybeHandle<Context>());
549 JSFrameSpecialization frame_specialization(data->info()->osr_frame(),
550 data->jsgraph());
551 JSGlobalObjectSpecialization global_object_specialization(
552 &graph_reducer, data->jsgraph(),
553 data->info()->is_deoptimization_enabled()
554 ? JSGlobalObjectSpecialization::kDeoptimizationEnabled
555 : JSGlobalObjectSpecialization::kNoFlags,
556 data->native_context(), data->info()->dependencies());
557 JSNativeContextSpecialization native_context_specialization(
558 &graph_reducer, data->jsgraph(),
559 data->info()->is_deoptimization_enabled()
560 ? JSNativeContextSpecialization::kDeoptimizationEnabled
561 : JSNativeContextSpecialization::kNoFlags,
562 data->native_context(), data->info()->dependencies(), temp_zone);
563 JSInliningHeuristic inlining(&graph_reducer,
564 data->info()->is_inlining_enabled()
565 ? JSInliningHeuristic::kGeneralInlining
566 : JSInliningHeuristic::kRestrictedInlining,
567 temp_zone, data->info(), data->jsgraph());
568 AddReducer(data, &graph_reducer, &dead_code_elimination);
569 AddReducer(data, &graph_reducer, &common_reducer);
570 if (data->info()->is_frame_specializing()) {
571 AddReducer(data, &graph_reducer, &frame_specialization);
572 }
573 AddReducer(data, &graph_reducer, &global_object_specialization);
574 AddReducer(data, &graph_reducer, &native_context_specialization);
575 AddReducer(data, &graph_reducer, &context_specialization);
576 AddReducer(data, &graph_reducer, &call_reducer);
577 AddReducer(data, &graph_reducer, &inlining);
578 graph_reducer.ReduceGraph();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400579 }
580};
581
582
583struct TyperPhase {
584 static const char* phase_name() { return "typer"; }
585
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000586 void Run(PipelineData* data, Zone* temp_zone, Typer* typer) {
587 NodeVector roots(temp_zone);
588 data->jsgraph()->GetCachedNodes(&roots);
589 typer->Run(roots);
590 }
591};
592
593
594struct OsrDeconstructionPhase {
595 static const char* phase_name() { return "OSR deconstruction"; }
596
597 void Run(PipelineData* data, Zone* temp_zone) {
598 OsrHelper osr_helper(data->info());
599 osr_helper.Deconstruct(data->jsgraph(), data->common(), temp_zone);
600 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400601};
602
603
604struct TypedLoweringPhase {
605 static const char* phase_name() { return "typed lowering"; }
606
607 void Run(PipelineData* data, Zone* temp_zone) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000608 JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
609 DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
610 data->common());
611 LoadElimination load_elimination(&graph_reducer);
612 JSBuiltinReducer builtin_reducer(&graph_reducer, data->jsgraph());
613 JSTypedLowering::Flags typed_lowering_flags = JSTypedLowering::kNoFlags;
614 if (data->info()->is_deoptimization_enabled()) {
615 typed_lowering_flags |= JSTypedLowering::kDeoptimizationEnabled;
616 }
617 if (data->info()->shared_info()->HasBytecodeArray()) {
618 typed_lowering_flags |= JSTypedLowering::kDisableBinaryOpReduction;
619 }
620 JSTypedLowering typed_lowering(&graph_reducer, data->info()->dependencies(),
621 typed_lowering_flags, data->jsgraph(),
622 temp_zone);
623 JSIntrinsicLowering intrinsic_lowering(
624 &graph_reducer, data->jsgraph(),
625 data->info()->is_deoptimization_enabled()
626 ? JSIntrinsicLowering::kDeoptimizationEnabled
627 : JSIntrinsicLowering::kDeoptimizationDisabled);
628 CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
629 data->common(), data->machine());
630 AddReducer(data, &graph_reducer, &dead_code_elimination);
631 AddReducer(data, &graph_reducer, &builtin_reducer);
632 AddReducer(data, &graph_reducer, &typed_lowering);
633 AddReducer(data, &graph_reducer, &intrinsic_lowering);
634 AddReducer(data, &graph_reducer, &load_elimination);
635 AddReducer(data, &graph_reducer, &common_reducer);
636 graph_reducer.ReduceGraph();
637 }
638};
639
640
641struct BranchEliminationPhase {
642 static const char* phase_name() { return "branch condition elimination"; }
643
644 void Run(PipelineData* data, Zone* temp_zone) {
645 JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
646 BranchElimination branch_condition_elimination(&graph_reducer,
647 data->jsgraph(), temp_zone);
648 DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
649 data->common());
650 AddReducer(data, &graph_reducer, &branch_condition_elimination);
651 AddReducer(data, &graph_reducer, &dead_code_elimination);
652 graph_reducer.ReduceGraph();
653 }
654};
655
656
657struct EscapeAnalysisPhase {
658 static const char* phase_name() { return "escape analysis"; }
659
660 void Run(PipelineData* data, Zone* temp_zone) {
661 EscapeAnalysis escape_analysis(data->graph(), data->jsgraph()->common(),
662 temp_zone);
663 escape_analysis.Run();
664 JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
665 EscapeAnalysisReducer escape_reducer(&graph_reducer, data->jsgraph(),
666 &escape_analysis, temp_zone);
667 AddReducer(data, &graph_reducer, &escape_reducer);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400668 graph_reducer.ReduceGraph();
669 }
670};
671
672
673struct SimplifiedLoweringPhase {
674 static const char* phase_name() { return "simplified lowering"; }
675
676 void Run(PipelineData* data, Zone* temp_zone) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000677 SimplifiedLowering lowering(data->jsgraph(), temp_zone,
678 data->source_positions());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400679 lowering.LowerAllNodes();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000680 JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
681 DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
682 data->common());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400683 SimplifiedOperatorReducer simple_reducer(data->jsgraph());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000684 ValueNumberingReducer value_numbering(temp_zone);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400685 MachineOperatorReducer machine_reducer(data->jsgraph());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000686 CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
687 data->common(), data->machine());
688 AddReducer(data, &graph_reducer, &dead_code_elimination);
689 AddReducer(data, &graph_reducer, &simple_reducer);
690 AddReducer(data, &graph_reducer, &value_numbering);
691 AddReducer(data, &graph_reducer, &machine_reducer);
692 AddReducer(data, &graph_reducer, &common_reducer);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400693 graph_reducer.ReduceGraph();
694 }
695};
696
697
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000698struct ControlFlowOptimizationPhase {
699 static const char* phase_name() { return "control flow optimization"; }
700
701 void Run(PipelineData* data, Zone* temp_zone) {
702 ControlFlowOptimizer optimizer(data->graph(), data->common(),
703 data->machine(), temp_zone);
704 optimizer.Optimize();
705 }
706};
707
708
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400709struct ChangeLoweringPhase {
710 static const char* phase_name() { return "change lowering"; }
711
712 void Run(PipelineData* data, Zone* temp_zone) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000713 JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
714 DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
715 data->common());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400716 SimplifiedOperatorReducer simple_reducer(data->jsgraph());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000717 ValueNumberingReducer value_numbering(temp_zone);
718 ChangeLowering lowering(data->jsgraph());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400719 MachineOperatorReducer machine_reducer(data->jsgraph());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000720 CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
721 data->common(), data->machine());
722 AddReducer(data, &graph_reducer, &dead_code_elimination);
723 AddReducer(data, &graph_reducer, &simple_reducer);
724 AddReducer(data, &graph_reducer, &value_numbering);
725 AddReducer(data, &graph_reducer, &lowering);
726 AddReducer(data, &graph_reducer, &machine_reducer);
727 AddReducer(data, &graph_reducer, &common_reducer);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400728 graph_reducer.ReduceGraph();
729 }
730};
731
732
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000733struct EarlyGraphTrimmingPhase {
734 static const char* phase_name() { return "early graph trimming"; }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400735 void Run(PipelineData* data, Zone* temp_zone) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000736 GraphTrimmer trimmer(temp_zone, data->graph());
737 NodeVector roots(temp_zone);
738 data->jsgraph()->GetCachedNodes(&roots);
739 trimmer.TrimGraph(roots.begin(), roots.end());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400740 }
741};
742
743
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000744struct LateGraphTrimmingPhase {
745 static const char* phase_name() { return "late graph trimming"; }
746 void Run(PipelineData* data, Zone* temp_zone) {
747 GraphTrimmer trimmer(temp_zone, data->graph());
748 NodeVector roots(temp_zone);
749 data->jsgraph()->GetCachedNodes(&roots);
750 trimmer.TrimGraph(roots.begin(), roots.end());
751 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400752};
753
754
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000755struct StressLoopPeelingPhase {
756 static const char* phase_name() { return "stress loop peeling"; }
757
758 void Run(PipelineData* data, Zone* temp_zone) {
759 // Peel the first outer loop for testing.
760 // TODO(titzer): peel all loops? the N'th loop? Innermost loops?
761 LoopTree* loop_tree = LoopFinder::BuildLoopTree(data->graph(), temp_zone);
762 if (loop_tree != nullptr && loop_tree->outer_loops().size() > 0) {
763 LoopPeeler::Peel(data->graph(), data->common(), loop_tree,
764 loop_tree->outer_loops()[0], temp_zone);
765 }
766 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400767};
768
769
770struct GenericLoweringPhase {
771 static const char* phase_name() { return "generic lowering"; }
772
773 void Run(PipelineData* data, Zone* temp_zone) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000774 JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
775 JSContextRelaxation context_relaxing;
776 DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
777 data->common());
778 CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
779 data->common(), data->machine());
780 JSGenericLowering generic_lowering(data->info()->is_typing_enabled(),
781 data->jsgraph());
782 SelectLowering select_lowering(data->jsgraph()->graph(),
783 data->jsgraph()->common());
784 TailCallOptimization tco(data->common(), data->graph());
785 AddReducer(data, &graph_reducer, &context_relaxing);
786 AddReducer(data, &graph_reducer, &dead_code_elimination);
787 AddReducer(data, &graph_reducer, &common_reducer);
788 AddReducer(data, &graph_reducer, &generic_lowering);
789 AddReducer(data, &graph_reducer, &select_lowering);
790 AddReducer(data, &graph_reducer, &tco);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400791 graph_reducer.ReduceGraph();
792 }
793};
794
795
796struct ComputeSchedulePhase {
797 static const char* phase_name() { return "scheduling"; }
798
799 void Run(PipelineData* data, Zone* temp_zone) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000800 Schedule* schedule = Scheduler::ComputeSchedule(
801 temp_zone, data->graph(), data->info()->is_splitting_enabled()
802 ? Scheduler::kSplitNodes
803 : Scheduler::kNoFlags);
804 if (FLAG_turbo_verify) ScheduleVerifier::Run(schedule);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400805 data->set_schedule(schedule);
806 }
807};
808
809
810struct InstructionSelectionPhase {
811 static const char* phase_name() { return "select instructions"; }
812
813 void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000814 InstructionSelector selector(
815 temp_zone, data->graph()->NodeCount(), linkage, data->sequence(),
816 data->schedule(), data->source_positions(),
817 data->info()->is_source_positions_enabled()
818 ? InstructionSelector::kAllSourcePositions
819 : InstructionSelector::kCallSourcePositions);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400820 selector.SelectInstructions();
821 }
822};
823
824
825struct MeetRegisterConstraintsPhase {
826 static const char* phase_name() { return "meet register constraints"; }
827
828 void Run(PipelineData* data, Zone* temp_zone) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000829 ConstraintBuilder builder(data->register_allocation_data());
830 builder.MeetRegisterConstraints();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400831 }
832};
833
834
835struct ResolvePhisPhase {
836 static const char* phase_name() { return "resolve phis"; }
837
838 void Run(PipelineData* data, Zone* temp_zone) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000839 ConstraintBuilder builder(data->register_allocation_data());
840 builder.ResolvePhis();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400841 }
842};
843
844
845struct BuildLiveRangesPhase {
846 static const char* phase_name() { return "build live ranges"; }
847
848 void Run(PipelineData* data, Zone* temp_zone) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000849 LiveRangeBuilder builder(data->register_allocation_data(), temp_zone);
850 builder.BuildLiveRanges();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400851 }
852};
853
854
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000855struct SplinterLiveRangesPhase {
856 static const char* phase_name() { return "splinter live ranges"; }
857
858 void Run(PipelineData* data, Zone* temp_zone) {
859 LiveRangeSeparator live_range_splinterer(data->register_allocation_data(),
860 temp_zone);
861 live_range_splinterer.Splinter();
862 }
863};
864
865
866template <typename RegAllocator>
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400867struct AllocateGeneralRegistersPhase {
868 static const char* phase_name() { return "allocate general registers"; }
869
870 void Run(PipelineData* data, Zone* temp_zone) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000871 RegAllocator allocator(data->register_allocation_data(), GENERAL_REGISTERS,
872 temp_zone);
873 allocator.AllocateRegisters();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400874 }
875};
876
877
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000878template <typename RegAllocator>
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400879struct AllocateDoubleRegistersPhase {
880 static const char* phase_name() { return "allocate double registers"; }
881
882 void Run(PipelineData* data, Zone* temp_zone) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000883 RegAllocator allocator(data->register_allocation_data(), DOUBLE_REGISTERS,
884 temp_zone);
885 allocator.AllocateRegisters();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400886 }
887};
888
889
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000890struct MergeSplintersPhase {
891 static const char* phase_name() { return "merge splintered ranges"; }
892 void Run(PipelineData* pipeline_data, Zone* temp_zone) {
893 RegisterAllocationData* data = pipeline_data->register_allocation_data();
894 LiveRangeMerger live_range_merger(data, temp_zone);
895 live_range_merger.Merge();
896 }
897};
898
899
900struct LocateSpillSlotsPhase {
901 static const char* phase_name() { return "locate spill slots"; }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400902
903 void Run(PipelineData* data, Zone* temp_zone) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000904 SpillSlotLocator locator(data->register_allocation_data());
905 locator.LocateSpillSlots();
906 }
907};
908
909
910struct AssignSpillSlotsPhase {
911 static const char* phase_name() { return "assign spill slots"; }
912
913 void Run(PipelineData* data, Zone* temp_zone) {
914 OperandAssigner assigner(data->register_allocation_data());
915 assigner.AssignSpillSlots();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400916 }
917};
918
919
920struct CommitAssignmentPhase {
921 static const char* phase_name() { return "commit assignment"; }
922
923 void Run(PipelineData* data, Zone* temp_zone) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000924 OperandAssigner assigner(data->register_allocation_data());
925 assigner.CommitAssignment();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400926 }
927};
928
929
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000930struct PopulateReferenceMapsPhase {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400931 static const char* phase_name() { return "populate pointer maps"; }
932
933 void Run(PipelineData* data, Zone* temp_zone) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000934 ReferenceMapPopulator populator(data->register_allocation_data());
935 populator.PopulateReferenceMaps();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400936 }
937};
938
939
940struct ConnectRangesPhase {
941 static const char* phase_name() { return "connect ranges"; }
942
943 void Run(PipelineData* data, Zone* temp_zone) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000944 LiveRangeConnector connector(data->register_allocation_data());
945 connector.ConnectRanges(temp_zone);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400946 }
947};
948
949
950struct ResolveControlFlowPhase {
951 static const char* phase_name() { return "resolve control flow"; }
952
953 void Run(PipelineData* data, Zone* temp_zone) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000954 LiveRangeConnector connector(data->register_allocation_data());
955 connector.ResolveControlFlow(temp_zone);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400956 }
957};
958
959
960struct OptimizeMovesPhase {
961 static const char* phase_name() { return "optimize moves"; }
962
963 void Run(PipelineData* data, Zone* temp_zone) {
964 MoveOptimizer move_optimizer(temp_zone, data->sequence());
965 move_optimizer.Run();
966 }
967};
968
969
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000970struct FrameElisionPhase {
971 static const char* phase_name() { return "frame elision"; }
972
973 void Run(PipelineData* data, Zone* temp_zone) {
974 FrameElider(data->sequence()).Run();
975 }
976};
977
978
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400979struct JumpThreadingPhase {
980 static const char* phase_name() { return "jump threading"; }
981
982 void Run(PipelineData* data, Zone* temp_zone) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000983 ZoneVector<RpoNumber> result(temp_zone);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400984 if (JumpThreading::ComputeForwarding(temp_zone, result, data->sequence())) {
985 JumpThreading::ApplyForwarding(result, data->sequence());
986 }
987 }
988};
989
990
991struct GenerateCodePhase {
992 static const char* phase_name() { return "generate code"; }
993
994 void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage) {
995 CodeGenerator generator(data->frame(), linkage, data->sequence(),
996 data->info());
997 data->set_code(generator.GenerateCode());
998 }
999};
1000
1001
1002struct PrintGraphPhase {
1003 static const char* phase_name() { return nullptr; }
1004
1005 void Run(PipelineData* data, Zone* temp_zone, const char* phase) {
1006 CompilationInfo* info = data->info();
1007 Graph* graph = data->graph();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001008
1009 { // Print JSON.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001010 FILE* json_file = OpenVisualizerLogFile(info, nullptr, "json", "a+");
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001011 if (json_file == nullptr) return;
1012 OFStream json_of(json_file);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001013 json_of << "{\"name\":\"" << phase << "\",\"type\":\"graph\",\"data\":"
1014 << AsJSON(*graph, data->source_positions()) << "},\n";
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001015 fclose(json_file);
1016 }
1017
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001018 if (FLAG_trace_turbo_graph) { // Simple textual RPO.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001019 OFStream os(stdout);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001020 os << "-- Graph after " << phase << " -- " << std::endl;
1021 os << AsRPO(*graph);
1022 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001023 }
1024};
1025
1026
1027struct VerifyGraphPhase {
1028 static const char* phase_name() { return nullptr; }
1029
1030 void Run(PipelineData* data, Zone* temp_zone, const bool untyped) {
1031 Verifier::Run(data->graph(), FLAG_turbo_types && !untyped
1032 ? Verifier::TYPED
1033 : Verifier::UNTYPED);
1034 }
1035};
1036
1037
1038void Pipeline::BeginPhaseKind(const char* phase_kind_name) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001039 if (data_->pipeline_statistics() != nullptr) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001040 data_->pipeline_statistics()->BeginPhaseKind(phase_kind_name);
1041 }
1042}
1043
1044
1045void Pipeline::RunPrintAndVerify(const char* phase, bool untyped) {
1046 if (FLAG_trace_turbo) {
1047 Run<PrintGraphPhase>(phase);
1048 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001049 if (FLAG_turbo_verify) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001050 Run<VerifyGraphPhase>(untyped);
1051 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001052}
1053
1054
1055Handle<Code> Pipeline::GenerateCode() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001056 // TODO(mstarzinger): This is just a temporary hack to make TurboFan work,
1057 // the correct solution is to restore the context register after invoking
1058 // builtins from full-codegen.
1059 if (Context::IsJSBuiltin(isolate()->native_context(), info()->closure())) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001060 return Handle<Code>::null();
1061 }
1062
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001063 ZonePool zone_pool;
1064 base::SmartPointer<PipelineStatistics> pipeline_statistics;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001065
1066 if (FLAG_turbo_stats) {
1067 pipeline_statistics.Reset(new PipelineStatistics(info(), &zone_pool));
1068 pipeline_statistics->BeginPhaseKind("initializing");
1069 }
1070
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001071 if (FLAG_trace_turbo) {
1072 FILE* json_file = OpenVisualizerLogFile(info(), nullptr, "json", "w+");
1073 if (json_file != nullptr) {
1074 OFStream json_of(json_file);
1075 Handle<Script> script = info()->script();
1076 FunctionLiteral* function = info()->literal();
1077 base::SmartArrayPointer<char> function_name = info()->GetDebugName();
1078 int pos = info()->shared_info()->start_position();
1079 json_of << "{\"function\":\"" << function_name.get()
1080 << "\", \"sourcePosition\":" << pos << ", \"source\":\"";
1081 if (!script->IsUndefined() && !script->source()->IsUndefined()) {
1082 DisallowHeapAllocation no_allocation;
1083 int start = function->start_position();
1084 int len = function->end_position() - start;
1085 String::SubStringRange source(String::cast(script->source()), start,
1086 len);
1087 for (const auto& c : source) {
1088 json_of << AsEscapedUC16ForJSON(c);
1089 }
1090 }
1091 json_of << "\",\n\"phases\":[";
1092 fclose(json_file);
1093 }
1094 }
1095
1096 PipelineData data(&zone_pool, info(), pipeline_statistics.get());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001097 this->data_ = &data;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001098
1099 BeginPhaseKind("graph creation");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001100
1101 if (FLAG_trace_turbo) {
1102 OFStream os(stdout);
1103 os << "---------------------------------------------------\n"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001104 << "Begin compiling method " << info()->GetDebugName().get()
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001105 << " using Turbofan" << std::endl;
1106 TurboCfgFile tcf(isolate());
1107 tcf << AsC1VCompilation(info());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001108 }
1109
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001110 data.source_positions()->AddDecorator();
1111
1112 if (FLAG_loop_assignment_analysis) {
1113 Run<LoopAssignmentAnalysisPhase>();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001114 }
1115
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001116 if (info()->is_typing_enabled()) {
1117 Run<TypeHintAnalysisPhase>();
1118 }
1119
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001120 Run<GraphBuilderPhase>();
1121 if (data.compilation_failed()) return Handle<Code>::null();
1122 RunPrintAndVerify("Initial untyped", true);
1123
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001124 // Perform OSR deconstruction.
1125 if (info()->is_osr()) {
1126 Run<OsrDeconstructionPhase>();
1127 RunPrintAndVerify("OSR deconstruction", true);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001128 }
1129
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001130 // Perform function context specialization and inlining (if enabled).
1131 Run<InliningPhase>();
1132 RunPrintAndVerify("Inlined", true);
1133
1134 // Remove dead->live edges from the graph.
1135 Run<EarlyGraphTrimmingPhase>();
1136 RunPrintAndVerify("Early trimmed", true);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001137
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001138 if (FLAG_print_turbo_replay) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001139 // Print a replay of the initial graph.
1140 GraphReplayPrinter::PrintReplay(data.graph());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001141 }
1142
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001143 base::SmartPointer<Typer> typer;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001144 if (info()->is_typing_enabled()) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001145 // Type the graph.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001146 typer.Reset(new Typer(isolate(), data.graph(),
1147 info()->is_deoptimization_enabled()
1148 ? Typer::kDeoptimizationEnabled
1149 : Typer::kNoFlags,
1150 info()->dependencies()));
1151 Run<TyperPhase>(typer.get());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001152 RunPrintAndVerify("Typed");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001153 }
1154
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001155 BeginPhaseKind("lowering");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001156
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001157 if (info()->is_typing_enabled()) {
1158 // Lower JSOperators where we can determine types.
1159 Run<TypedLoweringPhase>();
1160 RunPrintAndVerify("Lowered typed");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001161
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001162 if (FLAG_turbo_stress_loop_peeling) {
1163 Run<StressLoopPeelingPhase>();
1164 RunPrintAndVerify("Loop peeled");
1165 }
1166
1167 if (FLAG_turbo_escape) {
1168 Run<EscapeAnalysisPhase>();
1169 RunPrintAndVerify("Escape Analysed");
1170 }
1171
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001172 // Lower simplified operators and insert changes.
1173 Run<SimplifiedLoweringPhase>();
1174 RunPrintAndVerify("Lowered simplified");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001175
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001176 Run<BranchEliminationPhase>();
1177 RunPrintAndVerify("Branch conditions eliminated");
1178
1179 // Optimize control flow.
1180 if (FLAG_turbo_cf_optimization) {
1181 Run<ControlFlowOptimizationPhase>();
1182 RunPrintAndVerify("Control flow optimized");
1183 }
1184
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001185 // Lower changes that have been inserted before.
1186 Run<ChangeLoweringPhase>();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001187 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001188 RunPrintAndVerify("Lowered changes", true);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001189 }
1190
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001191 // Lower any remaining generic JSOperators.
1192 Run<GenericLoweringPhase>();
1193 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works.
1194 RunPrintAndVerify("Lowered generic", true);
1195
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001196 Run<LateGraphTrimmingPhase>();
1197 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works.
1198 RunPrintAndVerify("Late trimmed", true);
1199
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001200 BeginPhaseKind("block building");
1201
1202 data.source_positions()->RemoveDecorator();
1203
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001204 // Kill the Typer and thereby uninstall the decorator (if any).
1205 typer.Reset(nullptr);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001206
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001207 return ScheduleAndGenerateCode(
1208 Linkage::ComputeIncoming(data.instruction_zone(), info()));
1209}
1210
1211
1212Handle<Code> Pipeline::GenerateCodeForCodeStub(Isolate* isolate,
1213 CallDescriptor* call_descriptor,
1214 Graph* graph, Schedule* schedule,
1215 Code::Kind kind,
1216 const char* debug_name) {
1217 CompilationInfo info(debug_name, isolate, graph->zone());
1218 info.set_output_code_kind(kind);
1219
1220 // Construct a pipeline for scheduling and code generation.
1221 ZonePool zone_pool;
1222 PipelineData data(&zone_pool, &info, graph, schedule);
1223 base::SmartPointer<PipelineStatistics> pipeline_statistics;
1224 if (FLAG_turbo_stats) {
1225 pipeline_statistics.Reset(new PipelineStatistics(&info, &zone_pool));
1226 pipeline_statistics->BeginPhaseKind("stub codegen");
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001227 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001228
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001229 Pipeline pipeline(&info);
1230 pipeline.data_ = &data;
1231 DCHECK_NOT_NULL(data.schedule());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001232
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001233 if (FLAG_trace_turbo) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001234 FILE* json_file = OpenVisualizerLogFile(&info, nullptr, "json", "w+");
1235 if (json_file != nullptr) {
1236 OFStream json_of(json_file);
1237 json_of << "{\"function\":\"" << info.GetDebugName().get()
1238 << "\", \"source\":\"\",\n\"phases\":[";
1239 fclose(json_file);
1240 }
1241 pipeline.Run<PrintGraphPhase>("Machine");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001242 }
1243
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001244 return pipeline.ScheduleAndGenerateCode(call_descriptor);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001245}
1246
1247
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001248Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info,
1249 Graph* graph,
1250 Schedule* schedule) {
1251 CallDescriptor* call_descriptor =
1252 Linkage::ComputeIncoming(info->zone(), info);
1253 return GenerateCodeForTesting(info, call_descriptor, graph, schedule);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001254}
1255
1256
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001257Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info,
1258 CallDescriptor* call_descriptor,
1259 Graph* graph,
1260 Schedule* schedule) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001261 // Construct a pipeline for scheduling and code generation.
1262 ZonePool zone_pool;
1263 PipelineData data(&zone_pool, info, graph, schedule);
1264 base::SmartPointer<PipelineStatistics> pipeline_statistics;
1265 if (FLAG_turbo_stats) {
1266 pipeline_statistics.Reset(new PipelineStatistics(info, &zone_pool));
1267 pipeline_statistics->BeginPhaseKind("test codegen");
1268 }
1269
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001270 Pipeline pipeline(info);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001271 pipeline.data_ = &data;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001272 if (data.schedule() == nullptr) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001273 // TODO(rossberg): Should this really be untyped?
1274 pipeline.RunPrintAndVerify("Machine", true);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001275 }
1276
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001277 return pipeline.ScheduleAndGenerateCode(call_descriptor);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001278}
1279
1280
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001281bool Pipeline::AllocateRegistersForTesting(const RegisterConfiguration* config,
1282 InstructionSequence* sequence,
1283 bool run_verifier) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001284 CompilationInfo info("testing", sequence->isolate(), sequence->zone());
1285 ZonePool zone_pool;
1286 PipelineData data(&zone_pool, &info, sequence);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001287 Pipeline pipeline(&info);
1288 pipeline.data_ = &data;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001289 pipeline.AllocateRegisters(config, nullptr, run_verifier);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001290 return !data.compilation_failed();
1291}
1292
1293
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001294Handle<Code> Pipeline::ScheduleAndGenerateCode(
1295 CallDescriptor* call_descriptor) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001296 PipelineData* data = this->data_;
1297
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001298 DCHECK_NOT_NULL(data->graph());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001299
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001300 if (data->schedule() == nullptr) Run<ComputeSchedulePhase>();
1301 TraceSchedule(data->info(), data->schedule());
1302
1303 BasicBlockProfiler::Data* profiler_data = nullptr;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001304 if (FLAG_turbo_profiling) {
1305 profiler_data = BasicBlockInstrumentor::Instrument(info(), data->graph(),
1306 data->schedule());
1307 }
1308
1309 data->InitializeInstructionSequence();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001310
1311 // Select and schedule instructions covering the scheduled graph.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001312 Linkage linkage(call_descriptor);
1313 Run<InstructionSelectionPhase>(&linkage);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001314
1315 if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) {
1316 TurboCfgFile tcf(isolate());
1317 tcf << AsC1V("CodeGen", data->schedule(), data->source_positions(),
1318 data->sequence());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001319 }
1320
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001321 std::ostringstream source_position_output;
1322 if (FLAG_trace_turbo) {
1323 // Output source position information before the graph is deleted.
1324 data_->source_positions()->Print(source_position_output);
1325 }
1326
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001327 data->DeleteGraphZone();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001328
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001329 BeginPhaseKind("register allocation");
1330
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001331 bool run_verifier = FLAG_turbo_verify_allocation;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001332 // Allocate registers.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001333 AllocateRegisters(
1334 RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN),
1335 call_descriptor, run_verifier);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001336 if (data->compilation_failed()) {
1337 info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001338 return Handle<Code>();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001339 }
1340
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001341 BeginPhaseKind("code generation");
1342
1343 // Optimimize jumps.
1344 if (FLAG_turbo_jt) {
1345 Run<JumpThreadingPhase>();
1346 }
1347
1348 // Generate final machine code.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001349 Run<GenerateCodePhase>(&linkage);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001350
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001351 Handle<Code> code = data->code();
1352 if (profiler_data != nullptr) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001353#if ENABLE_DISASSEMBLER
1354 std::ostringstream os;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001355 code->Disassemble(nullptr, os);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001356 profiler_data->SetCode(&os);
1357#endif
1358 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001359
1360 info()->SetCode(code);
1361 v8::internal::CodeGenerator::PrintCode(code, info());
1362
1363 if (FLAG_trace_turbo) {
1364 FILE* json_file = OpenVisualizerLogFile(info(), nullptr, "json", "a+");
1365 if (json_file != nullptr) {
1366 OFStream json_of(json_file);
1367 json_of
1368 << "{\"name\":\"disassembly\",\"type\":\"disassembly\",\"data\":\"";
1369#if ENABLE_DISASSEMBLER
1370 std::stringstream disassembly_stream;
1371 code->Disassemble(nullptr, disassembly_stream);
1372 std::string disassembly_string(disassembly_stream.str());
1373 for (const auto& c : disassembly_string) {
1374 json_of << AsEscapedUC16ForJSON(c);
1375 }
1376#endif // ENABLE_DISASSEMBLER
1377 json_of << "\"}\n],\n";
1378 json_of << "\"nodePositions\":";
1379 json_of << source_position_output.str();
1380 json_of << "}";
1381 fclose(json_file);
1382 }
1383 OFStream os(stdout);
1384 os << "---------------------------------------------------\n"
1385 << "Finished compiling method " << info()->GetDebugName().get()
1386 << " using Turbofan" << std::endl;
1387 }
1388
1389 return code;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001390}
1391
1392
1393void Pipeline::AllocateRegisters(const RegisterConfiguration* config,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001394 CallDescriptor* descriptor,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001395 bool run_verifier) {
1396 PipelineData* data = this->data_;
1397
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001398 // Don't track usage for this zone in compiler stats.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001399 base::SmartPointer<Zone> verifier_zone;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001400 RegisterAllocatorVerifier* verifier = nullptr;
1401 if (run_verifier) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001402 verifier_zone.Reset(new Zone());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001403 verifier = new (verifier_zone.get()) RegisterAllocatorVerifier(
1404 verifier_zone.get(), config, data->sequence());
1405 }
1406
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001407 base::SmartArrayPointer<char> debug_name;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001408#ifdef DEBUG
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001409 debug_name = info()->GetDebugName();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001410#endif
1411
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001412 data->InitializeRegisterAllocationData(config, descriptor, debug_name.get());
1413 if (info()->is_osr()) {
1414 OsrHelper osr_helper(info());
1415 osr_helper.SetupFrame(data->frame());
1416 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001417
1418 Run<MeetRegisterConstraintsPhase>();
1419 Run<ResolvePhisPhase>();
1420 Run<BuildLiveRangesPhase>();
1421 if (FLAG_trace_turbo_graph) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001422 OFStream os(stdout);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001423 PrintableInstructionSequence printable = {config, data->sequence()};
1424 os << "----- Instruction sequence before register allocation -----\n"
1425 << printable;
1426 }
1427 if (verifier != nullptr) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001428 CHECK(!data->register_allocation_data()->ExistsUseWithoutDefinition());
1429 CHECK(data->register_allocation_data()
1430 ->RangesDefinedInDeferredStayInDeferred());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001431 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001432
1433 if (FLAG_turbo_preprocess_ranges) {
1434 Run<SplinterLiveRangesPhase>();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001435 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001436
1437 if (FLAG_turbo_greedy_regalloc) {
1438 Run<AllocateGeneralRegistersPhase<GreedyAllocator>>();
1439 Run<AllocateDoubleRegistersPhase<GreedyAllocator>>();
1440 } else {
1441 Run<AllocateGeneralRegistersPhase<LinearScanAllocator>>();
1442 Run<AllocateDoubleRegistersPhase<LinearScanAllocator>>();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001443 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001444
1445 if (FLAG_turbo_preprocess_ranges) {
1446 Run<MergeSplintersPhase>();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001447 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001448
1449 if (FLAG_turbo_frame_elision) {
1450 Run<LocateSpillSlotsPhase>();
1451 Run<FrameElisionPhase>();
1452 }
1453
1454 Run<AssignSpillSlotsPhase>();
1455
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001456 Run<CommitAssignmentPhase>();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001457 Run<PopulateReferenceMapsPhase>();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001458 Run<ConnectRangesPhase>();
1459 Run<ResolveControlFlowPhase>();
1460 if (FLAG_turbo_move_optimization) {
1461 Run<OptimizeMovesPhase>();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001462 }
1463
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001464 if (FLAG_trace_turbo_graph) {
1465 OFStream os(stdout);
1466 PrintableInstructionSequence printable = {config, data->sequence()};
1467 os << "----- Instruction sequence after register allocation -----\n"
1468 << printable;
1469 }
1470
1471 if (verifier != nullptr) {
1472 verifier->VerifyAssignment();
1473 verifier->VerifyGapMoves();
1474 }
1475
1476 if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) {
1477 TurboCfgFile tcf(data->isolate());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001478 tcf << AsC1VRegisterAllocationData("CodeGen",
1479 data->register_allocation_data());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001480 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001481
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001482 data->DeleteRegisterAllocationZone();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001483}
1484
1485} // namespace compiler
1486} // namespace internal
1487} // namespace v8