Chromium Code Reviews

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: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
« no previous file with comments | « src/compiler/pipeline.h ('k') | no next file » | 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...)
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),
52 graph_zone_scope_(zone_pool_), 54 graph_zone_scope_(zone_pool_),
53 graph_zone_(graph_zone_scope_.zone()), 55 graph_zone_(graph_zone_scope_.zone()),
54 graph_(new (graph_zone()) Graph(graph_zone())), 56 graph_(new (graph_zone()) Graph(graph_zone())),
55 source_positions_(new SourcePositionTable(graph())), 57 source_positions_(new SourcePositionTable(graph())),
56 machine_(new (graph_zone()) MachineOperatorBuilder( 58 machine_(new (graph_zone()) MachineOperatorBuilder(
57 graph_zone(), kMachPtr, 59 graph_zone(), kMachPtr,
58 InstructionSelector::SupportedMachineOperatorFlags())), 60 InstructionSelector::SupportedMachineOperatorFlags())),
59 common_(new (graph_zone()) CommonOperatorBuilder(graph_zone())), 61 common_(new (graph_zone()) CommonOperatorBuilder(graph_zone())),
60 javascript_(new (graph_zone()) JSOperatorBuilder(graph_zone())), 62 javascript_(new (graph_zone()) JSOperatorBuilder(graph_zone())),
61 jsgraph_(new (graph_zone()) 63 jsgraph_(new (graph_zone())
62 JSGraph(graph(), common(), javascript(), machine())), 64 JSGraph(graph(), common(), javascript(), machine())),
63 typer_(new Typer(graph(), info->context())), 65 typer_(new Typer(graph(), info->context())),
64 schedule_(NULL), 66 context_node_(nullptr),
67 schedule_(nullptr),
65 instruction_zone_scope_(zone_pool_), 68 instruction_zone_scope_(zone_pool_),
66 instruction_zone_(instruction_zone_scope_.zone()) {} 69 instruction_zone_(instruction_zone_scope_.zone()) {}
67 70
71
68 // For machine graph testing only. 72 // For machine graph testing only.
69 PipelineData(Graph* graph, Schedule* schedule, ZonePool* zone_pool) 73 PipelineData(Graph* graph, Schedule* schedule, ZonePool* zone_pool)
70 : isolate_(graph->zone()->isolate()), 74 : isolate_(graph->zone()->isolate()),
71 outer_zone_(NULL), 75 info_(nullptr),
76 outer_zone_(nullptr),
72 zone_pool_(zone_pool), 77 zone_pool_(zone_pool),
73 pipeline_statistics_(NULL), 78 pipeline_statistics_(nullptr),
79 compilation_failed_(false),
74 graph_zone_scope_(zone_pool_), 80 graph_zone_scope_(zone_pool_),
75 graph_zone_(NULL), 81 graph_zone_(nullptr),
76 graph_(graph), 82 graph_(graph),
77 source_positions_(new SourcePositionTable(graph)), 83 source_positions_(new SourcePositionTable(graph)),
78 machine_(NULL), 84 machine_(nullptr),
79 common_(NULL), 85 common_(nullptr),
80 javascript_(NULL), 86 javascript_(nullptr),
81 jsgraph_(NULL), 87 jsgraph_(nullptr),
82 typer_(NULL), 88 typer_(nullptr),
89 context_node_(nullptr),
83 schedule_(schedule), 90 schedule_(schedule),
84 instruction_zone_scope_(zone_pool_), 91 instruction_zone_scope_(zone_pool_),
85 instruction_zone_(instruction_zone_scope_.zone()) {} 92 instruction_zone_(instruction_zone_scope_.zone()) {}
86 93
87 ~PipelineData() { 94 ~PipelineData() {
88 DeleteInstructionZone(); 95 DeleteInstructionZone();
89 DeleteGraphZone(); 96 DeleteGraphZone();
90 } 97 }
91 98
92 Isolate* isolate() const { return isolate_; } 99 Isolate* isolate() const { return isolate_; }
100 CompilationInfo* info() const { return info_; }
93 ZonePool* zone_pool() const { return zone_pool_; } 101 ZonePool* zone_pool() const { return zone_pool_; }
94 PipelineStatistics* pipeline_statistics() { return pipeline_statistics_; } 102 PipelineStatistics* pipeline_statistics() { return pipeline_statistics_; }
103 bool compilation_failed() const { return compilation_failed_; }
104 void set_compilation_failed() { compilation_failed_ = true; }
95 105
96 Zone* graph_zone() const { return graph_zone_; } 106 Zone* graph_zone() const { return graph_zone_; }
97 Graph* graph() const { return graph_; } 107 Graph* graph() const { return graph_; }
98 SourcePositionTable* source_positions() const { 108 SourcePositionTable* source_positions() const {
99 return source_positions_.get(); 109 return source_positions_.get();
100 } 110 }
101 MachineOperatorBuilder* machine() const { return machine_; } 111 MachineOperatorBuilder* machine() const { return machine_; }
102 CommonOperatorBuilder* common() const { return common_; } 112 CommonOperatorBuilder* common() const { return common_; }
103 JSOperatorBuilder* javascript() const { return javascript_; } 113 JSOperatorBuilder* javascript() const { return javascript_; }
104 JSGraph* jsgraph() const { return jsgraph_; } 114 JSGraph* jsgraph() const { return jsgraph_; }
105 Typer* typer() const { return typer_.get(); } 115 Typer* typer() const { return typer_.get(); }
116 Node* context_node() const { return context_node_; }
117 void set_context_node(Node* context_node) { context_node_ = context_node; }
118
106 Schedule* schedule() const { return schedule_; } 119 Schedule* schedule() const { return schedule_; }
107 void set_schedule(Schedule* schedule) { 120 void set_schedule(Schedule* schedule) {
108 DCHECK_EQ(NULL, schedule_); 121 DCHECK_EQ(nullptr, schedule_);
109 schedule_ = schedule; 122 schedule_ = schedule;
110 } 123 }
111 124
112 Zone* instruction_zone() const { return instruction_zone_; } 125 Zone* instruction_zone() const { return instruction_zone_; }
113 // RawMachineAssembler generally produces graphs which cannot be verified. 126 // RawMachineAssembler generally produces graphs which cannot be verified.
114 bool MayHaveUnverifiableGraph() const { return outer_zone_ == nullptr; } 127 bool MayHaveUnverifiableGraph() const { return outer_zone_ == nullptr; }
115 128
116 void DeleteGraphZone() { 129 void DeleteGraphZone() {
117 // Destroy objects with destructors first. 130 // Destroy objects with destructors first.
118 source_positions_.Reset(NULL); 131 source_positions_.Reset(nullptr);
119 typer_.Reset(NULL); 132 typer_.Reset(nullptr);
120 if (graph_zone_ == NULL) return; 133 if (graph_zone_ == nullptr) return;
121 // Destroy zone and clear pointers. 134 // Destroy zone and clear pointers.
122 graph_zone_scope_.Destroy(); 135 graph_zone_scope_.Destroy();
123 graph_zone_ = NULL; 136 graph_zone_ = nullptr;
124 graph_ = NULL; 137 graph_ = nullptr;
125 machine_ = NULL; 138 machine_ = nullptr;
126 common_ = NULL; 139 common_ = nullptr;
127 javascript_ = NULL; 140 javascript_ = nullptr;
128 jsgraph_ = NULL; 141 jsgraph_ = nullptr;
129 schedule_ = NULL; 142 context_node_ = nullptr;
143 schedule_ = nullptr;
130 } 144 }
131 145
132 void DeleteInstructionZone() { 146 void DeleteInstructionZone() {
133 if (instruction_zone_ == NULL) return; 147 if (instruction_zone_ == NULL) return;
134 instruction_zone_scope_.Destroy(); 148 instruction_zone_scope_.Destroy();
135 instruction_zone_ = NULL; 149 instruction_zone_ = NULL;
136 } 150 }
137 151
138 private: 152 private:
139 Isolate* isolate_; 153 Isolate* isolate_;
154 CompilationInfo* info_;
140 Zone* outer_zone_; 155 Zone* outer_zone_;
141 ZonePool* zone_pool_; 156 ZonePool* zone_pool_;
142 PipelineStatistics* pipeline_statistics_; 157 PipelineStatistics* pipeline_statistics_;
158 bool compilation_failed_;
143 159
144 ZonePool::Scope graph_zone_scope_; 160 ZonePool::Scope graph_zone_scope_;
145 Zone* graph_zone_; 161 Zone* graph_zone_;
146 // All objects in the following group of fields are allocated in graph_zone_. 162 // 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. 163 // They are all set to NULL when the graph_zone_ is destroyed.
148 Graph* graph_; 164 Graph* graph_;
149 // TODO(dcarney): make this into a ZoneObject. 165 // TODO(dcarney): make this into a ZoneObject.
150 SmartPointer<SourcePositionTable> source_positions_; 166 SmartPointer<SourcePositionTable> source_positions_;
151 MachineOperatorBuilder* machine_; 167 MachineOperatorBuilder* machine_;
152 CommonOperatorBuilder* common_; 168 CommonOperatorBuilder* common_;
153 JSOperatorBuilder* javascript_; 169 JSOperatorBuilder* javascript_;
154 JSGraph* jsgraph_; 170 JSGraph* jsgraph_;
155 // TODO(dcarney): make this into a ZoneObject. 171 // TODO(dcarney): make this into a ZoneObject.
156 SmartPointer<Typer> typer_; 172 SmartPointer<Typer> typer_;
173 Node* context_node_;
157 Schedule* schedule_; 174 Schedule* schedule_;
158 175
159 // All objects in the following group of fields are allocated in 176 // 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 177 // instruction_zone_. They are all set to NULL when the instruction_zone_ is
161 // destroyed. 178 // destroyed.
162 ZonePool::Scope instruction_zone_scope_; 179 ZonePool::Scope instruction_zone_scope_;
163 Zone* instruction_zone_; 180 Zone* instruction_zone_;
164 181
165 DISALLOW_COPY_AND_ASSIGN(PipelineData); 182 DISALLOW_COPY_AND_ASSIGN(PipelineData);
166 }; 183 };
167 184
168 185
169 static inline bool VerifyGraphs() { 186 static inline bool VerifyGraphs() {
170 #ifdef DEBUG 187 #ifdef DEBUG
171 return true; 188 return true;
172 #else 189 #else
173 return FLAG_turbo_verify; 190 return FLAG_turbo_verify;
174 #endif 191 #endif
175 } 192 }
176 193
177 194
178 struct TurboCfgFile : public std::ofstream { 195 struct TurboCfgFile : public std::ofstream {
179 explicit TurboCfgFile(Isolate* isolate) 196 explicit TurboCfgFile(Isolate* isolate)
180 : std::ofstream(isolate->GetTurboCfgFileName().c_str(), 197 : std::ofstream(isolate->GetTurboCfgFileName().c_str(),
181 std::ios_base::app) {} 198 std::ios_base::app) {}
182 }; 199 };
183 200
184 201
185 void Pipeline::VerifyAndPrintGraph( 202 static void TraceSchedule(Schedule* schedule) {
186 Graph* graph, const char* phase, bool untyped) { 203 if (!FLAG_trace_turbo) return;
187 if (FLAG_trace_turbo) { 204 OFStream os(stdout);
205 os << "-- Schedule --------------------------------------\n" << *schedule;
206 }
207
208
209 static SmartArrayPointer<char> GetDebugName(CompilationInfo* info) {
210 SmartArrayPointer<char> name;
211 if (info->IsStub()) {
212 if (info->code_stub() != NULL) {
213 CodeStub::Major major_key = info->code_stub()->MajorKey();
214 const char* major_name = CodeStub::MajorName(major_key, false);
215 size_t len = strlen(major_name);
216 name.Reset(new char[len]);
217 memcpy(name.get(), major_name, len);
218 }
219 } else {
220 AllowHandleDereference allow_deref;
221 name = info->function()->debug_name()->ToCString();
222 }
223 return name;
224 }
225
226
227 class AstGraphBuilderWithPositions : public AstGraphBuilder {
228 public:
229 explicit AstGraphBuilderWithPositions(Zone* local_zone, CompilationInfo* info,
230 JSGraph* jsgraph,
231 SourcePositionTable* source_positions)
232 : AstGraphBuilder(local_zone, info, jsgraph),
233 source_positions_(source_positions) {}
234
235 bool CreateGraph() {
236 SourcePositionTable::Scope pos(source_positions_,
237 SourcePosition::Unknown());
238 return AstGraphBuilder::CreateGraph();
239 }
240
241 #define DEF_VISIT(type) \
242 virtual void Visit##type(type* node) OVERRIDE { \
243 SourcePositionTable::Scope pos(source_positions_, \
244 SourcePosition(node->position())); \
245 AstGraphBuilder::Visit##type(node); \
246 }
247 AST_NODE_LIST(DEF_VISIT)
248 #undef DEF_VISIT
249
250 Node* GetFunctionContext() { return AstGraphBuilder::GetFunctionContext(); }
251
252 private:
253 SourcePositionTable* source_positions_;
254 };
255
256
257 struct GraphBuilderPhase {
258 void Run(PipelineData* data) {
titzer 2014/11/14 14:03:40 I like this a lot better! Can we pull the phase_s
259 PhaseScope phase_scope(data->pipeline_statistics(), "graph builder");
260 ZonePool::Scope zone_scope(data->zone_pool());
261 AstGraphBuilderWithPositions graph_builder(zone_scope.zone(), data->info(),
262 data->jsgraph(),
263 data->source_positions());
264 if (!graph_builder.CreateGraph()) {
265 data->set_compilation_failed();
266 return;
267 }
268 data->set_context_node(graph_builder.GetFunctionContext());
269 }
270 };
271
272
273 struct ContextSpecializerPhase {
274 void Run(PipelineData* data) {
275 SourcePositionTable::Scope pos(data->source_positions(),
276 SourcePosition::Unknown());
277 JSContextSpecializer spec(data->info(), data->jsgraph(),
278 data->context_node());
279 spec.SpecializeToContext();
280 }
281 };
282
283
284 struct InliningPhase {
285 void Run(PipelineData* data) {
286 PhaseScope phase_scope(data->pipeline_statistics(), "inlining");
287 ZonePool::Scope zone_scope(data->zone_pool());
288 SourcePositionTable::Scope pos(data->source_positions(),
289 SourcePosition::Unknown());
290 JSInliner inliner(zone_scope.zone(), data->info(), data->jsgraph());
291 inliner.Inline();
292 }
293 };
294
295
296 struct TyperPhase {
297 void Run(PipelineData* data) {
298 PhaseScope phase_scope(data->pipeline_statistics(), "typer");
299 ZonePool::Scope zone_scope(data->zone_pool());
300 data->typer()->Run();
301 }
302 };
303
304
305 struct TypedLoweringPhase {
306 void Run(PipelineData* data) {
307 PhaseScope phase_scope(data->pipeline_statistics(), "typed lowering");
308 ZonePool::Scope zone_scope(data->zone_pool());
309 SourcePositionTable::Scope pos(data->source_positions(),
310 SourcePosition::Unknown());
311 ValueNumberingReducer vn_reducer(data->graph_zone());
312 JSTypedLowering lowering(data->jsgraph());
313 SimplifiedOperatorReducer simple_reducer(data->jsgraph());
314 GraphReducer graph_reducer(data->graph());
315 graph_reducer.AddReducer(&vn_reducer);
316 graph_reducer.AddReducer(&lowering);
317 graph_reducer.AddReducer(&simple_reducer);
318 graph_reducer.ReduceGraph();
319 }
320 };
321
322
323 struct SimplifiedLoweringPhase {
324 void Run(PipelineData* data) {
325 PhaseScope phase_scope(data->pipeline_statistics(), "simplified lowering");
326 ZonePool::Scope zone_scope(data->zone_pool());
327 SourcePositionTable::Scope pos(data->source_positions(),
328 SourcePosition::Unknown());
329 SimplifiedLowering lowering(data->jsgraph());
330 lowering.LowerAllNodes();
331 ValueNumberingReducer vn_reducer(data->graph_zone());
332 SimplifiedOperatorReducer simple_reducer(data->jsgraph());
333 GraphReducer graph_reducer(data->graph());
334 graph_reducer.AddReducer(&vn_reducer);
335 graph_reducer.AddReducer(&simple_reducer);
336 graph_reducer.ReduceGraph();
337 }
338 };
339
340
341 struct ChangeLoweringPhase {
342 void Run(PipelineData* data) {
343 PhaseScope phase_scope(data->pipeline_statistics(), "change lowering");
344 ZonePool::Scope zone_scope(data->zone_pool());
345 SourcePositionTable::Scope pos(data->source_positions(),
346 SourcePosition::Unknown());
347 Linkage linkage(data->graph_zone(), data->info());
348 ValueNumberingReducer vn_reducer(data->graph_zone());
349 SimplifiedOperatorReducer simple_reducer(data->jsgraph());
350 ChangeLowering lowering(data->jsgraph(), &linkage);
351 MachineOperatorReducer mach_reducer(data->jsgraph());
352 GraphReducer graph_reducer(data->graph());
353 // TODO(titzer): Figure out if we should run all reducers at once here.
354 graph_reducer.AddReducer(&vn_reducer);
355 graph_reducer.AddReducer(&simple_reducer);
356 graph_reducer.AddReducer(&lowering);
357 graph_reducer.AddReducer(&mach_reducer);
358 graph_reducer.ReduceGraph();
359 }
360 };
361
362
363 struct ControlReductionPhase {
364 void Run(PipelineData* data, const char* phase_name) {
365 PhaseScope phase_scope(data->pipeline_statistics(), phase_name);
366 ZonePool::Scope zone_scope(data->zone_pool());
367 SourcePositionTable::Scope pos(data->source_positions(),
368 SourcePosition::Unknown());
369 ControlReducer::ReduceGraph(zone_scope.zone(), data->jsgraph(),
370 data->common());
371 }
372 };
373
374
375 struct GenericLoweringPhase {
376 void Run(PipelineData* data) {
377 PhaseScope phase_scope(data->pipeline_statistics(), "generic lowering");
378 ZonePool::Scope zone_scope(data->zone_pool());
379 SourcePositionTable::Scope pos(data->source_positions(),
380 SourcePosition::Unknown());
381 JSGenericLowering generic(data->info(), data->jsgraph());
382 SelectLowering select(data->jsgraph()->graph(), data->jsgraph()->common());
383 GraphReducer graph_reducer(data->graph());
384 graph_reducer.AddReducer(&generic);
385 graph_reducer.AddReducer(&select);
386 graph_reducer.ReduceGraph();
387 }
388 };
389
390
391 struct ComputeSchedulePhase {
392 void Run(PipelineData* data) {
393 PhaseScope phase_scope(data->pipeline_statistics(), "scheduling");
394 ZonePool::Scope zone_scope(data->zone_pool());
395 Schedule* schedule =
396 Scheduler::ComputeSchedule(zone_scope.zone(), data->graph());
397 TraceSchedule(schedule);
398 if (VerifyGraphs()) ScheduleVerifier::Run(schedule);
399 data->set_schedule(schedule);
400 }
401 };
402
403
404 struct PrintGraphPhase {
405 void Run(PipelineData* data, const char* phase) {
406 CompilationInfo* info = data->info();
407 Graph* graph = data->graph();
188 char buffer[256]; 408 char buffer[256];
189 Vector<char> filename(buffer, sizeof(buffer)); 409 Vector<char> filename(buffer, sizeof(buffer));
190 SmartArrayPointer<char> functionname; 410 SmartArrayPointer<char> functionname;
191 if (!info_->shared_info().is_null()) { 411 if (!info->shared_info().is_null()) {
192 functionname = info_->shared_info()->DebugName()->ToCString(); 412 functionname = info->shared_info()->DebugName()->ToCString();
193 if (strlen(functionname.get()) > 0) { 413 if (strlen(functionname.get()) > 0) {
194 SNPrintF(filename, "turbo-%s-%s", functionname.get(), phase); 414 SNPrintF(filename, "turbo-%s-%s", functionname.get(), phase);
195 } else { 415 } else {
196 SNPrintF(filename, "turbo-%p-%s", static_cast<void*>(info_), phase); 416 SNPrintF(filename, "turbo-%p-%s", static_cast<void*>(info), phase);
197 } 417 }
198 } else { 418 } else {
199 SNPrintF(filename, "turbo-none-%s", phase); 419 SNPrintF(filename, "turbo-none-%s", phase);
200 } 420 }
201 std::replace(filename.start(), filename.start() + filename.length(), ' ', 421 std::replace(filename.start(), filename.start() + filename.length(), ' ',
202 '_'); 422 '_');
203 423
204 char dot_buffer[256]; 424 char dot_buffer[256];
205 Vector<char> dot_filename(dot_buffer, sizeof(dot_buffer)); 425 Vector<char> dot_filename(dot_buffer, sizeof(dot_buffer));
206 SNPrintF(dot_filename, "%s.dot", filename.start()); 426 SNPrintF(dot_filename, "%s.dot", filename.start());
207 FILE* dot_file = base::OS::FOpen(dot_filename.start(), "w+"); 427 FILE* dot_file = base::OS::FOpen(dot_filename.start(), "w+");
208 OFStream dot_of(dot_file); 428 OFStream dot_of(dot_file);
209 dot_of << AsDOT(*graph); 429 dot_of << AsDOT(*graph);
210 fclose(dot_file); 430 fclose(dot_file);
211 431
212 char json_buffer[256]; 432 char json_buffer[256];
213 Vector<char> json_filename(json_buffer, sizeof(json_buffer)); 433 Vector<char> json_filename(json_buffer, sizeof(json_buffer));
214 SNPrintF(json_filename, "%s.json", filename.start()); 434 SNPrintF(json_filename, "%s.json", filename.start());
215 FILE* json_file = base::OS::FOpen(json_filename.start(), "w+"); 435 FILE* json_file = base::OS::FOpen(json_filename.start(), "w+");
216 OFStream json_of(json_file); 436 OFStream json_of(json_file);
217 json_of << AsJSON(*graph); 437 json_of << AsJSON(*graph);
218 fclose(json_file); 438 fclose(json_file);
219 439
220 OFStream os(stdout); 440 OFStream os(stdout);
221 os << "-- " << phase << " graph printed to file " << filename.start() 441 os << "-- " << phase << " graph printed to file " << filename.start()
222 << "\n"; 442 << "\n";
223 } 443 }
444 };
445
446
447 struct VerifyGraphPhase {
448 void Run(PipelineData* data, const bool untyped) {
449 Verifier::Run(data->graph(), FLAG_turbo_types && !untyped
450 ? Verifier::TYPED
451 : Verifier::UNTYPED);
452 }
453 };
454
455
456 void Pipeline::RunPrintAndVerify(const char* phase, bool untyped) {
457 if (FLAG_trace_turbo) {
458 Run<PrintGraphPhase>(phase);
459 }
224 if (VerifyGraphs()) { 460 if (VerifyGraphs()) {
225 Verifier::Run(graph, 461 Run<VerifyGraphPhase>(untyped);
226 FLAG_turbo_types && !untyped ? Verifier::TYPED : Verifier::UNTYPED);
227 } 462 }
228 } 463 }
229 464
230 465
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() { 466 Handle<Code> Pipeline::GenerateCode() {
285 // This list must be kept in sync with DONT_TURBOFAN_NODE in ast.cc. 467 // This list must be kept in sync with DONT_TURBOFAN_NODE in ast.cc.
286 if (info()->function()->dont_optimize_reason() == kTryCatchStatement || 468 if (info()->function()->dont_optimize_reason() == kTryCatchStatement ||
287 info()->function()->dont_optimize_reason() == kTryFinallyStatement || 469 info()->function()->dont_optimize_reason() == kTryFinallyStatement ||
288 // TODO(turbofan): Make ES6 for-of work and remove this bailout. 470 // TODO(turbofan): Make ES6 for-of work and remove this bailout.
289 info()->function()->dont_optimize_reason() == kForOfStatement || 471 info()->function()->dont_optimize_reason() == kForOfStatement ||
290 // TODO(turbofan): Make super work and remove this bailout. 472 // TODO(turbofan): Make super work and remove this bailout.
291 info()->function()->dont_optimize_reason() == kSuperReference || 473 info()->function()->dont_optimize_reason() == kSuperReference ||
292 // TODO(turbofan): Make class literals work and remove this bailout. 474 // TODO(turbofan): Make class literals work and remove this bailout.
293 info()->function()->dont_optimize_reason() == kClassLiteral || 475 info()->function()->dont_optimize_reason() == kClassLiteral ||
294 // TODO(turbofan): Make OSR work and remove this bailout. 476 // TODO(turbofan): Make OSR work and remove this bailout.
295 info()->is_osr()) { 477 info()->is_osr()) {
296 return Handle<Code>::null(); 478 return Handle<Code>::null();
297 } 479 }
298 480
299 ZonePool zone_pool(isolate()); 481 ZonePool zone_pool(isolate());
482 SmartPointer<PipelineStatistics> pipeline_statistics;
300 483
301 SmartPointer<PipelineStatistics> pipeline_statistics;
302 if (FLAG_turbo_stats) { 484 if (FLAG_turbo_stats) {
303 pipeline_statistics.Reset(new PipelineStatistics(info(), &zone_pool)); 485 pipeline_statistics.Reset(new PipelineStatistics(info(), &zone_pool));
304 pipeline_statistics->BeginPhaseKind("graph creation"); 486 pipeline_statistics->BeginPhaseKind("graph creation");
305 } 487 }
306 488
489 PipelineData data(info(), &zone_pool, pipeline_statistics.get());
490 this->data_ = &data;
491
307 if (FLAG_trace_turbo) { 492 if (FLAG_trace_turbo) {
308 OFStream os(stdout); 493 OFStream os(stdout);
309 os << "---------------------------------------------------\n" 494 os << "---------------------------------------------------\n"
310 << "Begin compiling method " << GetDebugName(info()).get() 495 << "Begin compiling method " << GetDebugName(info()).get()
311 << " using Turbofan" << std::endl; 496 << " using Turbofan" << std::endl;
312 TurboCfgFile tcf(isolate()); 497 TurboCfgFile tcf(isolate());
313 tcf << AsC1VCompilation(info()); 498 tcf << AsC1VCompilation(info());
314 } 499 }
315 500
316 // Initialize the graph and builders.
317 PipelineData data(info(), &zone_pool, pipeline_statistics.get());
318
319 data.source_positions()->AddDecorator(); 501 data.source_positions()->AddDecorator();
320 502
321 Node* context_node; 503 Run<GraphBuilderPhase>();
322 { 504 if (data.compilation_failed()) return Handle<Code>::null();
323 PhaseScope phase_scope(pipeline_statistics.get(), "graph builder"); 505 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 506
331 VerifyAndPrintGraph(data.graph(), "Initial untyped", true); 507 Run<ControlReductionPhase>("early control reduction");
332 508 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 509
345 if (info()->is_context_specializing()) { 510 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. 511 // Specialize the code to the context as aggressively as possible.
349 JSContextSpecializer spec(info(), data.jsgraph(), context_node); 512 Run<ContextSpecializerPhase>();
350 spec.SpecializeToContext(); 513 RunPrintAndVerify("Context specialized", true);
351 VerifyAndPrintGraph(data.graph(), "Context specialized", true);
352 } 514 }
353 515
354 if (info()->is_inlining_enabled()) { 516 if (info()->is_inlining_enabled()) {
355 PhaseScope phase_scope(pipeline_statistics.get(), "inlining"); 517 Run<InliningPhase>();
356 SourcePositionTable::Scope pos(data.source_positions(), 518 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 } 519 }
363 520
364 // Print a replay of the initial graph.
365 if (FLAG_print_turbo_replay) { 521 if (FLAG_print_turbo_replay) {
522 // Print a replay of the initial graph.
366 GraphReplayPrinter::PrintReplay(data.graph()); 523 GraphReplayPrinter::PrintReplay(data.graph());
367 } 524 }
368 525
369 // Bailout here in case target architecture is not supported. 526 // Bailout here in case target architecture is not supported.
370 if (!SupportedTarget()) return Handle<Code>::null(); 527 if (!SupportedTarget()) return Handle<Code>::null();
371 528
372 if (info()->is_typing_enabled()) { 529 if (info()->is_typing_enabled()) {
373 { 530 // Type the graph.
374 // Type the graph. 531 Run<TyperPhase>();
375 PhaseScope phase_scope(pipeline_statistics.get(), "typer"); 532 RunPrintAndVerify("Typed");
376 data.typer()->Run();
377 VerifyAndPrintGraph(data.graph(), "Typed");
378 }
379 } 533 }
380 534
381 if (!pipeline_statistics.is_empty()) { 535 if (!pipeline_statistics.is_empty()) {
382 pipeline_statistics->BeginPhaseKind("lowering"); 536 data.pipeline_statistics()->BeginPhaseKind("lowering");
383 } 537 }
384 538
385 if (info()->is_typing_enabled()) { 539 if (info()->is_typing_enabled()) {
386 { 540 // Lower JSOperators where we can determine types.
387 // Lower JSOperators where we can determine types. 541 Run<TypedLoweringPhase>();
388 PhaseScope phase_scope(pipeline_statistics.get(), "typed lowering"); 542 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 543
400 VerifyAndPrintGraph(data.graph(), "Lowered typed"); 544 // Lower simplified operators and insert changes.
401 } 545 Run<SimplifiedLoweringPhase>();
402 { 546 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 547
416 VerifyAndPrintGraph(data.graph(), "Lowered simplified"); 548 // Lower changes that have been inserted before.
417 } 549 Run<ChangeLoweringPhase>();
418 { 550 // // TODO(jarin, rossberg): Remove UNTYPED once machine typing works.
419 // Lower changes that have been inserted before. 551 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 552
436 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. 553 Run<ControlReductionPhase>("late control reduction");
437 VerifyAndPrintGraph(data.graph(), "Lowered changes", true); 554 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 } 555 }
452 556
453 { 557 // Lower any remaining generic JSOperators.
454 // Lower any remaining generic JSOperators. 558 Run<GenericLoweringPhase>();
455 PhaseScope phase_scope(pipeline_statistics.get(), "generic lowering"); 559 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works.
456 SourcePositionTable::Scope pos(data.source_positions(), 560 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 561
469 if (!pipeline_statistics.is_empty()) { 562 if (!pipeline_statistics.is_empty()) {
470 pipeline_statistics->BeginPhaseKind("block building"); 563 data.pipeline_statistics()->BeginPhaseKind("block building");
471 } 564 }
472 565
473 data.source_positions()->RemoveDecorator(); 566 data.source_positions()->RemoveDecorator();
474 567
475 // Compute a schedule. 568 // Compute a schedule.
476 ComputeSchedule(&data); 569 Run<ComputeSchedulePhase>();
477 570
478 Handle<Code> code = Handle<Code>::null(); 571 Handle<Code> code = Handle<Code>::null();
479 { 572 {
480 // Generate optimized code. 573 // Generate optimized code.
481 Linkage linkage(data.instruction_zone(), info()); 574 Linkage linkage(data.instruction_zone(), info());
482 code = GenerateCode(&linkage, &data); 575 code = GenerateCode(&linkage, &data);
483 info()->SetCode(code); 576 info()->SetCode(code);
484 } 577 }
485 578
486 // Print optimized code. 579 // Print optimized code.
487 v8::internal::CodeGenerator::PrintCode(code, info()); 580 v8::internal::CodeGenerator::PrintCode(code, info());
488 581
489 if (FLAG_trace_turbo) { 582 if (FLAG_trace_turbo) {
490 OFStream os(stdout); 583 OFStream os(stdout);
491 os << "--------------------------------------------------\n" 584 os << "--------------------------------------------------\n"
492 << "Finished compiling method " << GetDebugName(info()).get() 585 << "Finished compiling method " << GetDebugName(info()).get()
493 << " using Turbofan" << std::endl; 586 << " using Turbofan" << std::endl;
494 } 587 }
495 588
496 return code; 589 return code;
497 } 590 }
498 591
499 592
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, 593 Handle<Code> Pipeline::GenerateCodeForMachineGraph(Linkage* linkage,
512 Graph* graph, 594 Graph* graph,
513 Schedule* schedule) { 595 Schedule* schedule) {
514 ZonePool zone_pool(isolate()); 596 ZonePool zone_pool(isolate());
515 CHECK(SupportedBackend()); 597 CHECK(SupportedBackend());
516 PipelineData data(graph, schedule, &zone_pool); 598 PipelineData data(graph, schedule, &zone_pool);
599 this->data_ = &data;
517 if (schedule == NULL) { 600 if (schedule == NULL) {
518 // TODO(rossberg): Should this really be untyped? 601 // TODO(rossberg): Should this really be untyped?
519 VerifyAndPrintGraph(graph, "Machine", true); 602 RunPrintAndVerify("Machine", true);
520 ComputeSchedule(&data); 603 Run<ComputeSchedulePhase>();
521 } else { 604 } else {
522 TraceSchedule(schedule); 605 TraceSchedule(schedule);
523 } 606 }
524 607
525 Handle<Code> code = GenerateCode(linkage, &data); 608 Handle<Code> code = GenerateCode(linkage, &data);
526 #if ENABLE_DISASSEMBLER 609 #if ENABLE_DISASSEMBLER
527 if (!code.is_null() && FLAG_print_opt_code) { 610 if (!code.is_null() && FLAG_print_opt_code) {
528 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer()); 611 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer());
529 OFStream os(tracing_scope.file()); 612 OFStream os(tracing_scope.file());
530 code->Disassemble("test code", os); 613 code->Disassemble("test code", os);
(...skipping 117 matching lines...)
648 } 731 }
649 732
650 733
651 void Pipeline::TearDown() { 734 void Pipeline::TearDown() {
652 InstructionOperand::TearDownCaches(); 735 InstructionOperand::TearDownCaches();
653 } 736 }
654 737
655 } // namespace compiler 738 } // namespace compiler
656 } // namespace internal 739 } // namespace internal
657 } // namespace v8 740 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/pipeline.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine