OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/pipeline.h" | 5 #include "src/compiler/pipeline.h" |
6 | 6 |
7 #include <fstream> // NOLINT(readability/streams) | 7 #include <fstream> // NOLINT(readability/streams) |
8 #include <sstream> | 8 #include <sstream> |
9 | 9 |
10 #include "src/base/platform/elapsed-timer.h" | 10 #include "src/base/platform/elapsed-timer.h" |
(...skipping 22 matching lines...) Expand all Loading... |
33 #include "src/compiler/value-numbering-reducer.h" | 33 #include "src/compiler/value-numbering-reducer.h" |
34 #include "src/compiler/verifier.h" | 34 #include "src/compiler/verifier.h" |
35 #include "src/compiler/zone-pool.h" | 35 #include "src/compiler/zone-pool.h" |
36 #include "src/ostreams.h" | 36 #include "src/ostreams.h" |
37 #include "src/utils.h" | 37 #include "src/utils.h" |
38 | 38 |
39 namespace v8 { | 39 namespace v8 { |
40 namespace internal { | 40 namespace internal { |
41 namespace compiler { | 41 namespace compiler { |
42 | 42 |
| 43 class PipelineData { |
| 44 public: |
| 45 explicit PipelineData(CompilationInfo* info, ZonePool* zone_pool, |
| 46 PipelineStatistics* pipeline_statistics) |
| 47 : isolate_(info->zone()->isolate()), |
| 48 outer_zone_(info->zone()), |
| 49 zone_pool_(zone_pool), |
| 50 pipeline_statistics_(pipeline_statistics), |
| 51 graph_zone_scope_(zone_pool_), |
| 52 graph_zone_(graph_zone_scope_.zone()), |
| 53 graph_(new (graph_zone()) Graph(graph_zone())), |
| 54 source_positions_(new SourcePositionTable(graph())), |
| 55 machine_(new (graph_zone()) MachineOperatorBuilder( |
| 56 kMachPtr, InstructionSelector::SupportedMachineOperatorFlags())), |
| 57 common_(new (graph_zone()) CommonOperatorBuilder(graph_zone())), |
| 58 javascript_(new (graph_zone()) JSOperatorBuilder(graph_zone())), |
| 59 jsgraph_(new (graph_zone()) |
| 60 JSGraph(graph(), common(), javascript(), machine())), |
| 61 typer_(new Typer(graph(), info->context())), |
| 62 schedule_(NULL), |
| 63 instruction_zone_scope_(zone_pool_), |
| 64 instruction_zone_(instruction_zone_scope_.zone()) {} |
| 65 |
| 66 // For machine graph testing only. |
| 67 PipelineData(Graph* graph, Schedule* schedule, ZonePool* zone_pool) |
| 68 : isolate_(graph->zone()->isolate()), |
| 69 outer_zone_(NULL), |
| 70 zone_pool_(zone_pool), |
| 71 pipeline_statistics_(NULL), |
| 72 graph_zone_scope_(zone_pool_), |
| 73 graph_zone_(NULL), |
| 74 graph_(graph), |
| 75 source_positions_(new SourcePositionTable(graph)), |
| 76 machine_(NULL), |
| 77 common_(NULL), |
| 78 javascript_(NULL), |
| 79 jsgraph_(NULL), |
| 80 typer_(NULL), |
| 81 schedule_(schedule), |
| 82 instruction_zone_scope_(zone_pool_), |
| 83 instruction_zone_(instruction_zone_scope_.zone()) {} |
| 84 |
| 85 ~PipelineData() { |
| 86 DeleteInstructionZone(); |
| 87 DeleteGraphZone(); |
| 88 } |
| 89 |
| 90 Isolate* isolate() const { return isolate_; } |
| 91 ZonePool* zone_pool() const { return zone_pool_; } |
| 92 PipelineStatistics* pipeline_statistics() { return pipeline_statistics_; } |
| 93 |
| 94 Zone* graph_zone() const { return graph_zone_; } |
| 95 Graph* graph() const { return graph_; } |
| 96 SourcePositionTable* source_positions() const { |
| 97 return source_positions_.get(); |
| 98 } |
| 99 MachineOperatorBuilder* machine() const { return machine_; } |
| 100 CommonOperatorBuilder* common() const { return common_; } |
| 101 JSOperatorBuilder* javascript() const { return javascript_; } |
| 102 JSGraph* jsgraph() const { return jsgraph_; } |
| 103 Typer* typer() const { return typer_.get(); } |
| 104 Schedule* schedule() const { return schedule_; } |
| 105 void set_schedule(Schedule* schedule) { |
| 106 DCHECK_EQ(NULL, schedule_); |
| 107 schedule_ = schedule; |
| 108 } |
| 109 |
| 110 Zone* instruction_zone() const { return instruction_zone_; } |
| 111 |
| 112 void DeleteGraphZone() { |
| 113 // Destroy objects with destructors first. |
| 114 source_positions_.Reset(NULL); |
| 115 typer_.Reset(NULL); |
| 116 if (graph_zone_ == NULL) return; |
| 117 // Destroy zone and clear pointers. |
| 118 graph_zone_scope_.Destroy(); |
| 119 graph_zone_ = NULL; |
| 120 graph_ = NULL; |
| 121 machine_ = NULL; |
| 122 common_ = NULL; |
| 123 javascript_ = NULL; |
| 124 jsgraph_ = NULL; |
| 125 schedule_ = NULL; |
| 126 } |
| 127 |
| 128 void DeleteInstructionZone() { |
| 129 if (instruction_zone_ == NULL) return; |
| 130 instruction_zone_scope_.Destroy(); |
| 131 instruction_zone_ = NULL; |
| 132 } |
| 133 |
| 134 private: |
| 135 Isolate* isolate_; |
| 136 Zone* outer_zone_; |
| 137 ZonePool* zone_pool_; |
| 138 PipelineStatistics* pipeline_statistics_; |
| 139 |
| 140 ZonePool::Scope graph_zone_scope_; |
| 141 Zone* graph_zone_; |
| 142 // All objects in the following group of fields are allocated in graph_zone_. |
| 143 // They are all set to NULL when the graph_zone_ is destroyed. |
| 144 Graph* graph_; |
| 145 // TODO(dcarney): make this into a ZoneObject. |
| 146 SmartPointer<SourcePositionTable> source_positions_; |
| 147 MachineOperatorBuilder* machine_; |
| 148 CommonOperatorBuilder* common_; |
| 149 JSOperatorBuilder* javascript_; |
| 150 JSGraph* jsgraph_; |
| 151 // TODO(dcarney): make this into a ZoneObject. |
| 152 SmartPointer<Typer> typer_; |
| 153 Schedule* schedule_; |
| 154 |
| 155 // All objects in the following group of fields are allocated in |
| 156 // instruction_zone_. They are all set to NULL when the instruction_zone_ is |
| 157 // destroyed. |
| 158 ZonePool::Scope instruction_zone_scope_; |
| 159 Zone* instruction_zone_; |
| 160 |
| 161 DISALLOW_COPY_AND_ASSIGN(PipelineData); |
| 162 }; |
| 163 |
| 164 |
43 static inline bool VerifyGraphs() { | 165 static inline bool VerifyGraphs() { |
44 #ifdef DEBUG | 166 #ifdef DEBUG |
45 return true; | 167 return true; |
46 #else | 168 #else |
47 return FLAG_turbo_verify; | 169 return FLAG_turbo_verify; |
48 #endif | 170 #endif |
49 } | 171 } |
50 | 172 |
51 | 173 |
52 struct TurboCfgFile : public std::ofstream { | 174 struct TurboCfgFile : public std::ofstream { |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 if (FLAG_trace_turbo) { | 285 if (FLAG_trace_turbo) { |
164 OFStream os(stdout); | 286 OFStream os(stdout); |
165 os << "---------------------------------------------------\n" | 287 os << "---------------------------------------------------\n" |
166 << "Begin compiling method " | 288 << "Begin compiling method " |
167 << info()->function()->debug_name()->ToCString().get() | 289 << info()->function()->debug_name()->ToCString().get() |
168 << " using Turbofan" << std::endl; | 290 << " using Turbofan" << std::endl; |
169 TurboCfgFile tcf(isolate()); | 291 TurboCfgFile tcf(isolate()); |
170 tcf << AsC1VCompilation(info()); | 292 tcf << AsC1VCompilation(info()); |
171 } | 293 } |
172 | 294 |
173 // Build the graph. | 295 // Initialize the graph and builders. |
174 Graph graph(zone()); | 296 PipelineData data(info(), &zone_pool, pipeline_statistics.get()); |
175 SourcePositionTable source_positions(&graph); | 297 |
176 source_positions.AddDecorator(); | 298 data.source_positions()->AddDecorator(); |
177 // TODO(turbofan): there is no need to type anything during initial graph | 299 |
178 // construction. This is currently only needed for the node cache, which the | |
179 // typer could sweep over later. | |
180 Typer typer(&graph, info()->context()); | |
181 MachineOperatorBuilder machine( | |
182 kMachPtr, InstructionSelector::SupportedMachineOperatorFlags()); | |
183 CommonOperatorBuilder common(zone()); | |
184 JSOperatorBuilder javascript(zone()); | |
185 JSGraph jsgraph(&graph, &common, &javascript, &machine); | |
186 Node* context_node; | 300 Node* context_node; |
187 { | 301 { |
188 PhaseScope phase_scope(pipeline_statistics.get(), "graph builder"); | 302 PhaseScope phase_scope(pipeline_statistics.get(), "graph builder"); |
189 ZonePool::Scope zone_scope(&zone_pool); | 303 ZonePool::Scope zone_scope(data.zone_pool()); |
190 AstGraphBuilderWithPositions graph_builder(zone_scope.zone(), info(), | 304 AstGraphBuilderWithPositions graph_builder( |
191 &jsgraph, &source_positions); | 305 zone_scope.zone(), info(), data.jsgraph(), data.source_positions()); |
192 graph_builder.CreateGraph(); | 306 graph_builder.CreateGraph(); |
193 context_node = graph_builder.GetFunctionContext(); | 307 context_node = graph_builder.GetFunctionContext(); |
194 } | 308 } |
195 { | 309 { |
196 PhaseScope phase_scope(pipeline_statistics.get(), "phi reduction"); | 310 PhaseScope phase_scope(pipeline_statistics.get(), "phi reduction"); |
197 PhiReducer phi_reducer; | 311 PhiReducer phi_reducer; |
198 GraphReducer graph_reducer(&graph); | 312 GraphReducer graph_reducer(data.graph()); |
199 graph_reducer.AddReducer(&phi_reducer); | 313 graph_reducer.AddReducer(&phi_reducer); |
200 graph_reducer.ReduceGraph(); | 314 graph_reducer.ReduceGraph(); |
201 // TODO(mstarzinger): Running reducer once ought to be enough for everyone. | 315 // TODO(mstarzinger): Running reducer once ought to be enough for everyone. |
202 graph_reducer.ReduceGraph(); | 316 graph_reducer.ReduceGraph(); |
203 graph_reducer.ReduceGraph(); | 317 graph_reducer.ReduceGraph(); |
204 } | 318 } |
205 | 319 |
206 VerifyAndPrintGraph(&graph, "Initial untyped", true); | 320 VerifyAndPrintGraph(data.graph(), "Initial untyped", true); |
207 | 321 |
208 if (info()->is_context_specializing()) { | 322 if (info()->is_context_specializing()) { |
209 SourcePositionTable::Scope pos(&source_positions, | 323 SourcePositionTable::Scope pos(data.source_positions(), |
210 SourcePosition::Unknown()); | 324 SourcePosition::Unknown()); |
211 // Specialize the code to the context as aggressively as possible. | 325 // Specialize the code to the context as aggressively as possible. |
212 JSContextSpecializer spec(info(), &jsgraph, context_node); | 326 JSContextSpecializer spec(info(), data.jsgraph(), context_node); |
213 spec.SpecializeToContext(); | 327 spec.SpecializeToContext(); |
214 VerifyAndPrintGraph(&graph, "Context specialized", true); | 328 VerifyAndPrintGraph(data.graph(), "Context specialized", true); |
215 } | 329 } |
216 | 330 |
217 if (info()->is_inlining_enabled()) { | 331 if (info()->is_inlining_enabled()) { |
218 PhaseScope phase_scope(pipeline_statistics.get(), "inlining"); | 332 PhaseScope phase_scope(pipeline_statistics.get(), "inlining"); |
219 SourcePositionTable::Scope pos(&source_positions, | 333 SourcePositionTable::Scope pos(data.source_positions(), |
220 SourcePosition::Unknown()); | 334 SourcePosition::Unknown()); |
221 ZonePool::Scope zone_scope(&zone_pool); | 335 ZonePool::Scope zone_scope(data.zone_pool()); |
222 JSInliner inliner(zone_scope.zone(), info(), &jsgraph); | 336 JSInliner inliner(zone_scope.zone(), info(), data.jsgraph()); |
223 inliner.Inline(); | 337 inliner.Inline(); |
224 VerifyAndPrintGraph(&graph, "Inlined", true); | 338 VerifyAndPrintGraph(data.graph(), "Inlined", true); |
225 } | 339 } |
226 | 340 |
227 // Print a replay of the initial graph. | 341 // Print a replay of the initial graph. |
228 if (FLAG_print_turbo_replay) { | 342 if (FLAG_print_turbo_replay) { |
229 GraphReplayPrinter::PrintReplay(&graph); | 343 GraphReplayPrinter::PrintReplay(data.graph()); |
230 } | 344 } |
231 | 345 |
232 // Bailout here in case target architecture is not supported. | 346 // Bailout here in case target architecture is not supported. |
233 if (!SupportedTarget()) return Handle<Code>::null(); | 347 if (!SupportedTarget()) return Handle<Code>::null(); |
234 | 348 |
235 if (info()->is_typing_enabled()) { | 349 if (info()->is_typing_enabled()) { |
236 { | 350 { |
237 // Type the graph. | 351 // Type the graph. |
238 PhaseScope phase_scope(pipeline_statistics.get(), "typer"); | 352 PhaseScope phase_scope(pipeline_statistics.get(), "typer"); |
239 typer.Run(); | 353 data.typer()->Run(); |
240 VerifyAndPrintGraph(&graph, "Typed"); | 354 VerifyAndPrintGraph(data.graph(), "Typed"); |
241 } | 355 } |
242 } | 356 } |
243 | 357 |
244 if (!pipeline_statistics.is_empty()) { | 358 if (!pipeline_statistics.is_empty()) { |
245 pipeline_statistics->BeginPhaseKind("lowering"); | 359 pipeline_statistics->BeginPhaseKind("lowering"); |
246 } | 360 } |
247 | 361 |
248 if (info()->is_typing_enabled()) { | 362 if (info()->is_typing_enabled()) { |
249 { | 363 { |
250 // Lower JSOperators where we can determine types. | 364 // Lower JSOperators where we can determine types. |
251 PhaseScope phase_scope(pipeline_statistics.get(), "typed lowering"); | 365 PhaseScope phase_scope(pipeline_statistics.get(), "typed lowering"); |
252 SourcePositionTable::Scope pos(&source_positions, | 366 SourcePositionTable::Scope pos(data.source_positions(), |
253 SourcePosition::Unknown()); | 367 SourcePosition::Unknown()); |
254 ValueNumberingReducer vn_reducer(zone()); | 368 ValueNumberingReducer vn_reducer(data.graph_zone()); |
255 JSTypedLowering lowering(&jsgraph); | 369 JSTypedLowering lowering(data.jsgraph()); |
256 SimplifiedOperatorReducer simple_reducer(&jsgraph); | 370 SimplifiedOperatorReducer simple_reducer(data.jsgraph()); |
257 GraphReducer graph_reducer(&graph); | 371 GraphReducer graph_reducer(data.graph()); |
258 graph_reducer.AddReducer(&vn_reducer); | 372 graph_reducer.AddReducer(&vn_reducer); |
259 graph_reducer.AddReducer(&lowering); | 373 graph_reducer.AddReducer(&lowering); |
260 graph_reducer.AddReducer(&simple_reducer); | 374 graph_reducer.AddReducer(&simple_reducer); |
261 graph_reducer.ReduceGraph(); | 375 graph_reducer.ReduceGraph(); |
262 | 376 |
263 VerifyAndPrintGraph(&graph, "Lowered typed"); | 377 VerifyAndPrintGraph(data.graph(), "Lowered typed"); |
264 } | 378 } |
265 { | 379 { |
266 // Lower simplified operators and insert changes. | 380 // Lower simplified operators and insert changes. |
267 PhaseScope phase_scope(pipeline_statistics.get(), "simplified lowering"); | 381 PhaseScope phase_scope(pipeline_statistics.get(), "simplified lowering"); |
268 SourcePositionTable::Scope pos(&source_positions, | 382 SourcePositionTable::Scope pos(data.source_positions(), |
269 SourcePosition::Unknown()); | 383 SourcePosition::Unknown()); |
270 SimplifiedLowering lowering(&jsgraph); | 384 SimplifiedLowering lowering(data.jsgraph()); |
271 lowering.LowerAllNodes(); | 385 lowering.LowerAllNodes(); |
272 ValueNumberingReducer vn_reducer(zone()); | 386 ValueNumberingReducer vn_reducer(data.graph_zone()); |
273 SimplifiedOperatorReducer simple_reducer(&jsgraph); | 387 SimplifiedOperatorReducer simple_reducer(data.jsgraph()); |
274 GraphReducer graph_reducer(&graph); | 388 GraphReducer graph_reducer(data.graph()); |
275 graph_reducer.AddReducer(&vn_reducer); | 389 graph_reducer.AddReducer(&vn_reducer); |
276 graph_reducer.AddReducer(&simple_reducer); | 390 graph_reducer.AddReducer(&simple_reducer); |
277 graph_reducer.ReduceGraph(); | 391 graph_reducer.ReduceGraph(); |
278 | 392 |
279 VerifyAndPrintGraph(&graph, "Lowered simplified"); | 393 VerifyAndPrintGraph(data.graph(), "Lowered simplified"); |
280 } | 394 } |
281 { | 395 { |
282 // Lower changes that have been inserted before. | 396 // Lower changes that have been inserted before. |
283 PhaseScope phase_scope(pipeline_statistics.get(), "change lowering"); | 397 PhaseScope phase_scope(pipeline_statistics.get(), "change lowering"); |
284 SourcePositionTable::Scope pos(&source_positions, | 398 SourcePositionTable::Scope pos(data.source_positions(), |
285 SourcePosition::Unknown()); | 399 SourcePosition::Unknown()); |
286 Linkage linkage(info()); | 400 Linkage linkage(info()); |
287 ValueNumberingReducer vn_reducer(zone()); | 401 ValueNumberingReducer vn_reducer(data.graph_zone()); |
288 SimplifiedOperatorReducer simple_reducer(&jsgraph); | 402 SimplifiedOperatorReducer simple_reducer(data.jsgraph()); |
289 ChangeLowering lowering(&jsgraph, &linkage); | 403 ChangeLowering lowering(data.jsgraph(), &linkage); |
290 MachineOperatorReducer mach_reducer(&jsgraph); | 404 MachineOperatorReducer mach_reducer(data.jsgraph()); |
291 GraphReducer graph_reducer(&graph); | 405 GraphReducer graph_reducer(data.graph()); |
292 // TODO(titzer): Figure out if we should run all reducers at once here. | 406 // TODO(titzer): Figure out if we should run all reducers at once here. |
293 graph_reducer.AddReducer(&vn_reducer); | 407 graph_reducer.AddReducer(&vn_reducer); |
294 graph_reducer.AddReducer(&simple_reducer); | 408 graph_reducer.AddReducer(&simple_reducer); |
295 graph_reducer.AddReducer(&lowering); | 409 graph_reducer.AddReducer(&lowering); |
296 graph_reducer.AddReducer(&mach_reducer); | 410 graph_reducer.AddReducer(&mach_reducer); |
297 graph_reducer.ReduceGraph(); | 411 graph_reducer.ReduceGraph(); |
298 | 412 |
299 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. | 413 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. |
300 VerifyAndPrintGraph(&graph, "Lowered changes", true); | 414 VerifyAndPrintGraph(data.graph(), "Lowered changes", true); |
301 } | 415 } |
302 | 416 |
303 { | 417 { |
304 PhaseScope phase_scope(pipeline_statistics.get(), "control reduction"); | 418 PhaseScope phase_scope(pipeline_statistics.get(), "control reduction"); |
305 SourcePositionTable::Scope pos(&source_positions, | 419 SourcePositionTable::Scope pos(data.source_positions(), |
306 SourcePosition::Unknown()); | 420 SourcePosition::Unknown()); |
307 ZonePool::Scope zone_scope(&zone_pool); | 421 ZonePool::Scope zone_scope(data.zone_pool()); |
308 ControlReducer::ReduceGraph(zone_scope.zone(), &jsgraph, &common); | 422 ControlReducer::ReduceGraph(zone_scope.zone(), data.jsgraph(), |
| 423 data.common()); |
309 | 424 |
310 VerifyAndPrintGraph(&graph, "Control reduced"); | 425 VerifyAndPrintGraph(data.graph(), "Control reduced"); |
311 } | 426 } |
312 } | 427 } |
313 | 428 |
314 { | 429 { |
315 // Lower any remaining generic JSOperators. | 430 // Lower any remaining generic JSOperators. |
316 PhaseScope phase_scope(pipeline_statistics.get(), "generic lowering"); | 431 PhaseScope phase_scope(pipeline_statistics.get(), "generic lowering"); |
317 SourcePositionTable::Scope pos(&source_positions, | 432 SourcePositionTable::Scope pos(data.source_positions(), |
318 SourcePosition::Unknown()); | 433 SourcePosition::Unknown()); |
319 JSGenericLowering lowering(info(), &jsgraph); | 434 JSGenericLowering lowering(info(), data.jsgraph()); |
320 GraphReducer graph_reducer(&graph); | 435 GraphReducer graph_reducer(data.graph()); |
321 graph_reducer.AddReducer(&lowering); | 436 graph_reducer.AddReducer(&lowering); |
322 graph_reducer.ReduceGraph(); | 437 graph_reducer.ReduceGraph(); |
323 | 438 |
324 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. | 439 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. |
325 VerifyAndPrintGraph(&graph, "Lowered generic", true); | 440 VerifyAndPrintGraph(data.graph(), "Lowered generic", true); |
326 } | 441 } |
327 | 442 |
328 if (!pipeline_statistics.is_empty()) { | 443 if (!pipeline_statistics.is_empty()) { |
329 pipeline_statistics->BeginPhaseKind("block building"); | 444 pipeline_statistics->BeginPhaseKind("block building"); |
330 } | 445 } |
331 | 446 |
332 source_positions.RemoveDecorator(); | 447 data.source_positions()->RemoveDecorator(); |
333 | 448 |
334 Schedule* schedule; | 449 // Compute a schedule. |
335 { | 450 ComputeSchedule(&data); |
336 PhaseScope phase_scope(pipeline_statistics.get(), "scheduling"); | |
337 // Compute a schedule. | |
338 schedule = ComputeSchedule(&zone_pool, &graph); | |
339 } | |
340 | 451 |
341 Handle<Code> code = Handle<Code>::null(); | 452 Handle<Code> code = Handle<Code>::null(); |
342 { | 453 { |
343 // Generate optimized code. | 454 // Generate optimized code. |
344 Linkage linkage(info()); | 455 Linkage linkage(info()); |
345 code = GenerateCode(pipeline_statistics.get(), &zone_pool, &linkage, &graph, | 456 code = GenerateCode(&linkage, &data); |
346 schedule, &source_positions); | |
347 info()->SetCode(code); | 457 info()->SetCode(code); |
348 } | 458 } |
349 | 459 |
350 // Print optimized code. | 460 // Print optimized code. |
351 v8::internal::CodeGenerator::PrintCode(code, info()); | 461 v8::internal::CodeGenerator::PrintCode(code, info()); |
352 | 462 |
353 if (FLAG_trace_turbo) { | 463 if (FLAG_trace_turbo) { |
354 OFStream os(stdout); | 464 OFStream os(stdout); |
355 os << "--------------------------------------------------\n" | 465 os << "--------------------------------------------------\n" |
356 << "Finished compiling method " | 466 << "Finished compiling method " |
357 << info()->function()->debug_name()->ToCString().get() | 467 << info()->function()->debug_name()->ToCString().get() |
358 << " using Turbofan" << std::endl; | 468 << " using Turbofan" << std::endl; |
359 } | 469 } |
360 | 470 |
361 return code; | 471 return code; |
362 } | 472 } |
363 | 473 |
364 | 474 |
365 Schedule* Pipeline::ComputeSchedule(ZonePool* zone_pool, Graph* graph) { | 475 void Pipeline::ComputeSchedule(PipelineData* data) { |
366 Schedule* schedule = Scheduler::ComputeSchedule(zone_pool, graph); | 476 PhaseScope phase_scope(data->pipeline_statistics(), "scheduling"); |
| 477 Schedule* schedule = |
| 478 Scheduler::ComputeSchedule(data->zone_pool(), data->graph()); |
367 TraceSchedule(schedule); | 479 TraceSchedule(schedule); |
368 if (VerifyGraphs()) ScheduleVerifier::Run(schedule); | 480 if (VerifyGraphs()) ScheduleVerifier::Run(schedule); |
369 return schedule; | 481 data->set_schedule(schedule); |
370 } | 482 } |
371 | 483 |
372 | 484 |
373 Handle<Code> Pipeline::GenerateCodeForMachineGraph(Linkage* linkage, | 485 Handle<Code> Pipeline::GenerateCodeForMachineGraph(Linkage* linkage, |
374 Graph* graph, | 486 Graph* graph, |
375 Schedule* schedule) { | 487 Schedule* schedule) { |
376 ZonePool zone_pool(isolate()); | 488 ZonePool zone_pool(isolate()); |
377 CHECK(SupportedBackend()); | 489 CHECK(SupportedBackend()); |
| 490 PipelineData data(graph, schedule, &zone_pool); |
378 if (schedule == NULL) { | 491 if (schedule == NULL) { |
379 // TODO(rossberg): Should this really be untyped? | 492 // TODO(rossberg): Should this really be untyped? |
380 VerifyAndPrintGraph(graph, "Machine", true); | 493 VerifyAndPrintGraph(graph, "Machine", true); |
381 schedule = ComputeSchedule(&zone_pool, graph); | 494 ComputeSchedule(&data); |
| 495 } else { |
| 496 TraceSchedule(schedule); |
382 } | 497 } |
383 TraceSchedule(schedule); | |
384 | 498 |
385 SourcePositionTable source_positions(graph); | 499 Handle<Code> code = GenerateCode(linkage, &data); |
386 Handle<Code> code = GenerateCode(NULL, &zone_pool, linkage, graph, schedule, | |
387 &source_positions); | |
388 #if ENABLE_DISASSEMBLER | 500 #if ENABLE_DISASSEMBLER |
389 if (!code.is_null() && FLAG_print_opt_code) { | 501 if (!code.is_null() && FLAG_print_opt_code) { |
390 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer()); | 502 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer()); |
391 OFStream os(tracing_scope.file()); | 503 OFStream os(tracing_scope.file()); |
392 code->Disassemble("test code", os); | 504 code->Disassemble("test code", os); |
393 } | 505 } |
394 #endif | 506 #endif |
395 return code; | 507 return code; |
396 } | 508 } |
397 | 509 |
398 | 510 |
399 Handle<Code> Pipeline::GenerateCode(PipelineStatistics* pipeline_statistics, | 511 Handle<Code> Pipeline::GenerateCode(Linkage* linkage, PipelineData* data) { |
400 ZonePool* zone_pool, Linkage* linkage, | |
401 Graph* graph, Schedule* schedule, | |
402 SourcePositionTable* source_positions) { | |
403 DCHECK_NOT_NULL(graph); | |
404 DCHECK_NOT_NULL(linkage); | 512 DCHECK_NOT_NULL(linkage); |
405 DCHECK_NOT_NULL(schedule); | 513 DCHECK_NOT_NULL(data->graph()); |
| 514 DCHECK_NOT_NULL(data->schedule()); |
406 CHECK(SupportedBackend()); | 515 CHECK(SupportedBackend()); |
407 | 516 |
408 BasicBlockProfiler::Data* profiler_data = NULL; | 517 BasicBlockProfiler::Data* profiler_data = NULL; |
409 if (FLAG_turbo_profiling) { | 518 if (FLAG_turbo_profiling) { |
410 profiler_data = BasicBlockInstrumentor::Instrument(info_, graph, schedule); | 519 profiler_data = BasicBlockInstrumentor::Instrument(info(), data->graph(), |
| 520 data->schedule()); |
411 } | 521 } |
412 | 522 |
413 Zone* instruction_zone = schedule->zone(); | 523 InstructionSequence sequence(data->instruction_zone(), data->graph(), |
414 InstructionSequence sequence(instruction_zone, graph, schedule); | 524 data->schedule()); |
415 | 525 |
416 // Select and schedule instructions covering the scheduled graph. | 526 // Select and schedule instructions covering the scheduled graph. |
417 { | 527 { |
418 PhaseScope phase_scope(pipeline_statistics, "select instructions"); | 528 PhaseScope phase_scope(data->pipeline_statistics(), "select instructions"); |
419 ZonePool::Scope zone_scope(zone_pool); | 529 ZonePool::Scope zone_scope(data->zone_pool()); |
420 InstructionSelector selector(zone_scope.zone(), linkage, &sequence, | 530 InstructionSelector selector(zone_scope.zone(), linkage, &sequence, |
421 schedule, source_positions); | 531 data->schedule(), data->source_positions()); |
422 selector.SelectInstructions(); | 532 selector.SelectInstructions(); |
423 } | 533 } |
424 | 534 |
425 if (FLAG_trace_turbo) { | 535 if (FLAG_trace_turbo) { |
426 OFStream os(stdout); | 536 OFStream os(stdout); |
427 os << "----- Instruction sequence before register allocation -----\n" | 537 os << "----- Instruction sequence before register allocation -----\n" |
428 << sequence; | 538 << sequence; |
429 TurboCfgFile tcf(isolate()); | 539 TurboCfgFile tcf(isolate()); |
430 tcf << AsC1V("CodeGen", schedule, source_positions, &sequence); | 540 tcf << AsC1V("CodeGen", data->schedule(), data->source_positions(), |
| 541 &sequence); |
431 } | 542 } |
432 | 543 |
433 if (pipeline_statistics != NULL) { | 544 data->DeleteGraphZone(); |
434 pipeline_statistics->BeginPhaseKind("register allocation"); | 545 |
| 546 if (data->pipeline_statistics() != NULL) { |
| 547 data->pipeline_statistics()->BeginPhaseKind("register allocation"); |
435 } | 548 } |
436 | 549 |
437 // Allocate registers. | 550 // Allocate registers. |
438 Frame frame; | 551 Frame frame; |
439 { | 552 { |
440 int node_count = graph->NodeCount(); | 553 int node_count = sequence.VirtualRegisterCount(); |
441 if (node_count > UnallocatedOperand::kMaxVirtualRegisters) { | 554 if (node_count > UnallocatedOperand::kMaxVirtualRegisters) { |
442 linkage->info()->AbortOptimization(kNotEnoughVirtualRegistersForValues); | 555 linkage->info()->AbortOptimization(kNotEnoughVirtualRegistersForValues); |
443 return Handle<Code>::null(); | 556 return Handle<Code>::null(); |
444 } | 557 } |
445 ZonePool::Scope zone_scope(zone_pool); | 558 ZonePool::Scope zone_scope(data->zone_pool()); |
446 RegisterAllocator allocator(zone_scope.zone(), &frame, linkage->info(), | 559 RegisterAllocator allocator(zone_scope.zone(), &frame, linkage->info(), |
447 &sequence); | 560 &sequence); |
448 if (!allocator.Allocate(pipeline_statistics)) { | 561 if (!allocator.Allocate(data->pipeline_statistics())) { |
449 linkage->info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc); | 562 linkage->info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc); |
450 return Handle<Code>::null(); | 563 return Handle<Code>::null(); |
451 } | 564 } |
452 if (FLAG_trace_turbo) { | 565 if (FLAG_trace_turbo) { |
453 TurboCfgFile tcf(isolate()); | 566 TurboCfgFile tcf(isolate()); |
454 tcf << AsC1VAllocator("CodeGen", &allocator); | 567 tcf << AsC1VAllocator("CodeGen", &allocator); |
455 } | 568 } |
456 } | 569 } |
457 | 570 |
458 if (FLAG_trace_turbo) { | 571 if (FLAG_trace_turbo) { |
459 OFStream os(stdout); | 572 OFStream os(stdout); |
460 os << "----- Instruction sequence after register allocation -----\n" | 573 os << "----- Instruction sequence after register allocation -----\n" |
461 << sequence; | 574 << sequence; |
462 } | 575 } |
463 | 576 |
464 if (pipeline_statistics != NULL) { | 577 if (data->pipeline_statistics() != NULL) { |
465 pipeline_statistics->BeginPhaseKind("code generation"); | 578 data->pipeline_statistics()->BeginPhaseKind("code generation"); |
466 } | 579 } |
467 | 580 |
468 // Generate native sequence. | 581 // Generate native sequence. |
469 Handle<Code> code; | 582 Handle<Code> code; |
470 { | 583 { |
471 PhaseScope phase_scope(pipeline_statistics, "generate code"); | 584 PhaseScope phase_scope(data->pipeline_statistics(), "generate code"); |
472 CodeGenerator generator(&frame, linkage, &sequence); | 585 CodeGenerator generator(&frame, linkage, &sequence); |
473 code = generator.GenerateCode(); | 586 code = generator.GenerateCode(); |
474 } | 587 } |
475 if (profiler_data != NULL) { | 588 if (profiler_data != NULL) { |
476 #if ENABLE_DISASSEMBLER | 589 #if ENABLE_DISASSEMBLER |
477 std::ostringstream os; | 590 std::ostringstream os; |
478 code->Disassemble(NULL, os); | 591 code->Disassemble(NULL, os); |
479 profiler_data->SetCode(&os); | 592 profiler_data->SetCode(&os); |
480 #endif | 593 #endif |
481 } | 594 } |
482 return code; | 595 return code; |
483 } | 596 } |
484 | 597 |
485 | 598 |
486 void Pipeline::SetUp() { | 599 void Pipeline::SetUp() { |
487 InstructionOperand::SetUpCaches(); | 600 InstructionOperand::SetUpCaches(); |
488 } | 601 } |
489 | 602 |
490 | 603 |
491 void Pipeline::TearDown() { | 604 void Pipeline::TearDown() { |
492 InstructionOperand::TearDownCaches(); | 605 InstructionOperand::TearDownCaches(); |
493 } | 606 } |
494 | 607 |
495 } // namespace compiler | 608 } // namespace compiler |
496 } // namespace internal | 609 } // namespace internal |
497 } // namespace v8 | 610 } // namespace v8 |
OLD | NEW |