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" | |
6 | |
7 #include <sstream> | 5 #include <sstream> |
8 | 6 |
9 #include "src/base/platform/elapsed-timer.h" | 7 #include "src/base/platform/elapsed-timer.h" |
10 #include "src/compiler/ast-graph-builder.h" | 8 #include "src/compiler/ast-graph-builder.h" |
11 #include "src/compiler/basic-block-instrumentor.h" | 9 #include "src/compiler/basic-block-instrumentor.h" |
12 #include "src/compiler/change-lowering.h" | 10 #include "src/compiler/change-lowering.h" |
13 #include "src/compiler/code-generator.h" | 11 #include "src/compiler/code-generator.h" |
14 #include "src/compiler/control-reducer.h" | 12 #include "src/compiler/control-reducer.h" |
15 #include "src/compiler/graph-replay.h" | 13 #include "src/compiler/graph-replay.h" |
16 #include "src/compiler/graph-visualizer.h" | 14 #include "src/compiler/graph-visualizer.h" |
17 #include "src/compiler/instruction.h" | 15 #include "src/compiler/instruction.h" |
18 #include "src/compiler/instruction-selector.h" | 16 #include "src/compiler/instruction-selector.h" |
19 #include "src/compiler/js-context-specialization.h" | 17 #include "src/compiler/js-context-specialization.h" |
20 #include "src/compiler/js-generic-lowering.h" | 18 #include "src/compiler/js-generic-lowering.h" |
21 #include "src/compiler/js-inlining.h" | 19 #include "src/compiler/js-inlining.h" |
22 #include "src/compiler/js-typed-lowering.h" | 20 #include "src/compiler/js-typed-lowering.h" |
23 #include "src/compiler/machine-operator-reducer.h" | 21 #include "src/compiler/machine-operator-reducer.h" |
24 #include "src/compiler/phi-reducer.h" | 22 #include "src/compiler/phi-reducer.h" |
| 23 #include "src/compiler/pipeline.h" |
| 24 #include "src/compiler/pipeline-statistics.h" |
25 #include "src/compiler/register-allocator.h" | 25 #include "src/compiler/register-allocator.h" |
26 #include "src/compiler/schedule.h" | 26 #include "src/compiler/schedule.h" |
27 #include "src/compiler/scheduler.h" | 27 #include "src/compiler/scheduler.h" |
28 #include "src/compiler/simplified-lowering.h" | 28 #include "src/compiler/simplified-lowering.h" |
29 #include "src/compiler/simplified-operator-reducer.h" | 29 #include "src/compiler/simplified-operator-reducer.h" |
30 #include "src/compiler/typer.h" | 30 #include "src/compiler/typer.h" |
31 #include "src/compiler/value-numbering-reducer.h" | 31 #include "src/compiler/value-numbering-reducer.h" |
32 #include "src/compiler/verifier.h" | 32 #include "src/compiler/verifier.h" |
33 #include "src/compiler/zone-pool.h" | 33 #include "src/compiler/zone-pool.h" |
34 #include "src/hydrogen.h" | |
35 #include "src/ostreams.h" | 34 #include "src/ostreams.h" |
36 #include "src/utils.h" | 35 #include "src/utils.h" |
37 | 36 |
38 namespace v8 { | 37 namespace v8 { |
39 namespace internal { | 38 namespace internal { |
40 namespace compiler { | 39 namespace compiler { |
41 | 40 |
42 class PhaseStats { | |
43 public: | |
44 enum PhaseKind { CREATE_GRAPH, OPTIMIZATION, CODEGEN }; | |
45 | |
46 PhaseStats(CompilationInfo* info, ZonePool* zone_pool, PhaseKind kind, | |
47 const char* name) | |
48 : info_(info), | |
49 stats_scope_(zone_pool), | |
50 kind_(kind), | |
51 name_(name), | |
52 size_(0) { | |
53 if (FLAG_turbo_stats) { | |
54 timer_.Start(); | |
55 size_ = info_->zone()->allocation_size(); | |
56 } | |
57 } | |
58 | |
59 ~PhaseStats() { | |
60 if (FLAG_turbo_stats) { | |
61 base::TimeDelta delta = timer_.Elapsed(); | |
62 size_t bytes = info_->zone()->allocation_size() + | |
63 stats_scope_.GetMaxAllocatedBytes() - size_; | |
64 HStatistics* stats = info_->isolate()->GetTStatistics(); | |
65 stats->SaveTiming(name_, delta, static_cast<int>(bytes)); | |
66 | |
67 switch (kind_) { | |
68 case CREATE_GRAPH: | |
69 stats->IncrementCreateGraph(delta); | |
70 break; | |
71 case OPTIMIZATION: | |
72 stats->IncrementOptimizeGraph(delta); | |
73 break; | |
74 case CODEGEN: | |
75 stats->IncrementGenerateCode(delta); | |
76 break; | |
77 } | |
78 } | |
79 } | |
80 | |
81 private: | |
82 CompilationInfo* info_; | |
83 ZonePool::StatsScope stats_scope_; | |
84 PhaseKind kind_; | |
85 const char* name_; | |
86 size_t size_; | |
87 base::ElapsedTimer timer_; | |
88 }; | |
89 | |
90 | |
91 static inline bool VerifyGraphs() { | 41 static inline bool VerifyGraphs() { |
92 #ifdef DEBUG | 42 #ifdef DEBUG |
93 return true; | 43 return true; |
94 #else | 44 #else |
95 return FLAG_turbo_verify; | 45 return FLAG_turbo_verify; |
96 #endif | 46 #endif |
97 } | 47 } |
98 | 48 |
99 | 49 |
100 void Pipeline::PrintCompilationStart() { | 50 void Pipeline::PrintCompilationStart() { |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 info()->function()->dont_optimize_reason() == kForOfStatement || | 169 info()->function()->dont_optimize_reason() == kForOfStatement || |
220 // TODO(turbofan): Make super work and remove this bailout. | 170 // TODO(turbofan): Make super work and remove this bailout. |
221 info()->function()->dont_optimize_reason() == kSuperReference || | 171 info()->function()->dont_optimize_reason() == kSuperReference || |
222 // TODO(turbofan): Make class literals work and remove this bailout. | 172 // TODO(turbofan): Make class literals work and remove this bailout. |
223 info()->function()->dont_optimize_reason() == kClassLiteral || | 173 info()->function()->dont_optimize_reason() == kClassLiteral || |
224 // TODO(turbofan): Make OSR work and remove this bailout. | 174 // TODO(turbofan): Make OSR work and remove this bailout. |
225 info()->is_osr()) { | 175 info()->is_osr()) { |
226 return Handle<Code>::null(); | 176 return Handle<Code>::null(); |
227 } | 177 } |
228 | 178 |
229 if (FLAG_turbo_stats) isolate()->GetTStatistics()->Initialize(info_); | 179 ZonePool zone_pool(isolate()); |
| 180 |
| 181 SmartPointer<PipelineStatistics> pipeline_statistics; |
| 182 if (FLAG_turbo_stats) { |
| 183 pipeline_statistics.Reset(new PipelineStatistics(info(), &zone_pool)); |
| 184 pipeline_statistics->BeginPhaseKind("create graph"); |
| 185 } |
230 | 186 |
231 if (FLAG_trace_turbo) { | 187 if (FLAG_trace_turbo) { |
232 OFStream os(stdout); | 188 OFStream os(stdout); |
233 os << "---------------------------------------------------\n" | 189 os << "---------------------------------------------------\n" |
234 << "Begin compiling method " | 190 << "Begin compiling method " |
235 << info()->function()->debug_name()->ToCString().get() | 191 << info()->function()->debug_name()->ToCString().get() |
236 << " using Turbofan" << std::endl; | 192 << " using Turbofan" << std::endl; |
237 PrintCompilationStart(); | 193 PrintCompilationStart(); |
238 } | 194 } |
239 | 195 |
240 ZonePool zone_pool(isolate()); | |
241 | |
242 // Build the graph. | 196 // Build the graph. |
243 Graph graph(zone()); | 197 Graph graph(zone()); |
244 SourcePositionTable source_positions(&graph); | 198 SourcePositionTable source_positions(&graph); |
245 source_positions.AddDecorator(); | 199 source_positions.AddDecorator(); |
246 // TODO(turbofan): there is no need to type anything during initial graph | 200 // TODO(turbofan): there is no need to type anything during initial graph |
247 // construction. This is currently only needed for the node cache, which the | 201 // construction. This is currently only needed for the node cache, which the |
248 // typer could sweep over later. | 202 // typer could sweep over later. |
249 Typer typer(&graph, info()->context()); | 203 Typer typer(&graph, info()->context()); |
250 MachineOperatorBuilder machine; | 204 MachineOperatorBuilder machine; |
251 CommonOperatorBuilder common(zone()); | 205 CommonOperatorBuilder common(zone()); |
252 JSOperatorBuilder javascript(zone()); | 206 JSOperatorBuilder javascript(zone()); |
253 JSGraph jsgraph(&graph, &common, &javascript, &machine); | 207 JSGraph jsgraph(&graph, &common, &javascript, &machine); |
254 Node* context_node; | 208 Node* context_node; |
255 { | 209 { |
256 PhaseStats graph_builder_stats(info(), &zone_pool, PhaseStats::CREATE_GRAPH, | 210 PhaseScope phase_scope(pipeline_statistics.get(), "graph builder"); |
257 "graph builder"); | |
258 ZonePool::Scope zone_scope(&zone_pool); | 211 ZonePool::Scope zone_scope(&zone_pool); |
259 AstGraphBuilderWithPositions graph_builder(zone_scope.zone(), info(), | 212 AstGraphBuilderWithPositions graph_builder(zone_scope.zone(), info(), |
260 &jsgraph, &source_positions); | 213 &jsgraph, &source_positions); |
261 graph_builder.CreateGraph(); | 214 graph_builder.CreateGraph(); |
262 context_node = graph_builder.GetFunctionContext(); | 215 context_node = graph_builder.GetFunctionContext(); |
263 } | 216 } |
264 { | 217 { |
265 PhaseStats phi_reducer_stats(info(), &zone_pool, PhaseStats::CREATE_GRAPH, | 218 PhaseScope phase_scope(pipeline_statistics.get(), "phi reduction"); |
266 "phi reduction"); | |
267 PhiReducer phi_reducer; | 219 PhiReducer phi_reducer; |
268 GraphReducer graph_reducer(&graph); | 220 GraphReducer graph_reducer(&graph); |
269 graph_reducer.AddReducer(&phi_reducer); | 221 graph_reducer.AddReducer(&phi_reducer); |
270 graph_reducer.ReduceGraph(); | 222 graph_reducer.ReduceGraph(); |
271 // TODO(mstarzinger): Running reducer once ought to be enough for everyone. | 223 // TODO(mstarzinger): Running reducer once ought to be enough for everyone. |
272 graph_reducer.ReduceGraph(); | 224 graph_reducer.ReduceGraph(); |
273 graph_reducer.ReduceGraph(); | 225 graph_reducer.ReduceGraph(); |
274 } | 226 } |
275 | 227 |
276 VerifyAndPrintGraph(&graph, "Initial untyped", true); | 228 VerifyAndPrintGraph(&graph, "Initial untyped", true); |
277 | 229 |
278 if (info()->is_context_specializing()) { | 230 if (info()->is_context_specializing()) { |
279 SourcePositionTable::Scope pos(&source_positions, | 231 SourcePositionTable::Scope pos(&source_positions, |
280 SourcePosition::Unknown()); | 232 SourcePosition::Unknown()); |
281 // Specialize the code to the context as aggressively as possible. | 233 // Specialize the code to the context as aggressively as possible. |
282 JSContextSpecializer spec(info(), &jsgraph, context_node); | 234 JSContextSpecializer spec(info(), &jsgraph, context_node); |
283 spec.SpecializeToContext(); | 235 spec.SpecializeToContext(); |
284 VerifyAndPrintGraph(&graph, "Context specialized", true); | 236 VerifyAndPrintGraph(&graph, "Context specialized", true); |
285 } | 237 } |
286 | 238 |
287 if (info()->is_inlining_enabled()) { | 239 if (info()->is_inlining_enabled()) { |
| 240 PhaseScope phase_scope(pipeline_statistics.get(), "inlining"); |
288 SourcePositionTable::Scope pos(&source_positions, | 241 SourcePositionTable::Scope pos(&source_positions, |
289 SourcePosition::Unknown()); | 242 SourcePosition::Unknown()); |
290 ZonePool::Scope zone_scope(&zone_pool); | 243 ZonePool::Scope zone_scope(&zone_pool); |
291 JSInliner inliner(zone_scope.zone(), info(), &jsgraph); | 244 JSInliner inliner(zone_scope.zone(), info(), &jsgraph); |
292 inliner.Inline(); | 245 inliner.Inline(); |
293 VerifyAndPrintGraph(&graph, "Inlined", true); | 246 VerifyAndPrintGraph(&graph, "Inlined", true); |
294 } | 247 } |
295 | 248 |
296 // Print a replay of the initial graph. | 249 // Print a replay of the initial graph. |
297 if (FLAG_print_turbo_replay) { | 250 if (FLAG_print_turbo_replay) { |
298 GraphReplayPrinter::PrintReplay(&graph); | 251 GraphReplayPrinter::PrintReplay(&graph); |
299 } | 252 } |
300 | 253 |
301 // Bailout here in case target architecture is not supported. | 254 // Bailout here in case target architecture is not supported. |
302 if (!SupportedTarget()) return Handle<Code>::null(); | 255 if (!SupportedTarget()) return Handle<Code>::null(); |
303 | 256 |
304 if (info()->is_typing_enabled()) { | 257 if (info()->is_typing_enabled()) { |
305 { | 258 { |
306 // Type the graph. | 259 // Type the graph. |
307 PhaseStats typer_stats(info(), &zone_pool, PhaseStats::CREATE_GRAPH, | 260 PhaseScope phase_scope(pipeline_statistics.get(), "typer"); |
308 "typer"); | |
309 typer.Run(); | 261 typer.Run(); |
310 VerifyAndPrintGraph(&graph, "Typed"); | 262 VerifyAndPrintGraph(&graph, "Typed"); |
311 } | 263 } |
| 264 } |
| 265 |
| 266 if (!pipeline_statistics.is_empty()) { |
| 267 pipeline_statistics->BeginPhaseKind("lowering"); |
| 268 } |
| 269 |
| 270 if (info()->is_typing_enabled()) { |
312 { | 271 { |
313 // Lower JSOperators where we can determine types. | 272 // Lower JSOperators where we can determine types. |
314 PhaseStats lowering_stats(info(), &zone_pool, PhaseStats::CREATE_GRAPH, | 273 PhaseScope phase_scope(pipeline_statistics.get(), "typed lowering"); |
315 "typed lowering"); | |
316 SourcePositionTable::Scope pos(&source_positions, | 274 SourcePositionTable::Scope pos(&source_positions, |
317 SourcePosition::Unknown()); | 275 SourcePosition::Unknown()); |
318 ValueNumberingReducer vn_reducer(zone()); | 276 ValueNumberingReducer vn_reducer(zone()); |
319 JSTypedLowering lowering(&jsgraph); | 277 JSTypedLowering lowering(&jsgraph); |
320 SimplifiedOperatorReducer simple_reducer(&jsgraph); | 278 SimplifiedOperatorReducer simple_reducer(&jsgraph); |
321 GraphReducer graph_reducer(&graph); | 279 GraphReducer graph_reducer(&graph); |
322 graph_reducer.AddReducer(&vn_reducer); | 280 graph_reducer.AddReducer(&vn_reducer); |
323 graph_reducer.AddReducer(&lowering); | 281 graph_reducer.AddReducer(&lowering); |
324 graph_reducer.AddReducer(&simple_reducer); | 282 graph_reducer.AddReducer(&simple_reducer); |
325 graph_reducer.ReduceGraph(); | 283 graph_reducer.ReduceGraph(); |
326 | 284 |
327 VerifyAndPrintGraph(&graph, "Lowered typed"); | 285 VerifyAndPrintGraph(&graph, "Lowered typed"); |
328 } | 286 } |
329 { | 287 { |
330 // Lower simplified operators and insert changes. | 288 // Lower simplified operators and insert changes. |
331 PhaseStats lowering_stats(info(), &zone_pool, PhaseStats::CREATE_GRAPH, | 289 PhaseScope phase_scope(pipeline_statistics.get(), "simplified lowering"); |
332 "simplified lowering"); | |
333 SourcePositionTable::Scope pos(&source_positions, | 290 SourcePositionTable::Scope pos(&source_positions, |
334 SourcePosition::Unknown()); | 291 SourcePosition::Unknown()); |
335 SimplifiedLowering lowering(&jsgraph); | 292 SimplifiedLowering lowering(&jsgraph); |
336 lowering.LowerAllNodes(); | 293 lowering.LowerAllNodes(); |
337 ValueNumberingReducer vn_reducer(zone()); | 294 ValueNumberingReducer vn_reducer(zone()); |
338 SimplifiedOperatorReducer simple_reducer(&jsgraph); | 295 SimplifiedOperatorReducer simple_reducer(&jsgraph); |
339 GraphReducer graph_reducer(&graph); | 296 GraphReducer graph_reducer(&graph); |
340 graph_reducer.AddReducer(&vn_reducer); | 297 graph_reducer.AddReducer(&vn_reducer); |
341 graph_reducer.AddReducer(&simple_reducer); | 298 graph_reducer.AddReducer(&simple_reducer); |
342 graph_reducer.ReduceGraph(); | 299 graph_reducer.ReduceGraph(); |
343 | 300 |
344 VerifyAndPrintGraph(&graph, "Lowered simplified"); | 301 VerifyAndPrintGraph(&graph, "Lowered simplified"); |
345 } | 302 } |
346 { | 303 { |
347 // Lower changes that have been inserted before. | 304 // Lower changes that have been inserted before. |
348 PhaseStats lowering_stats(info(), &zone_pool, PhaseStats::OPTIMIZATION, | 305 PhaseScope phase_scope(pipeline_statistics.get(), "change lowering"); |
349 "change lowering"); | |
350 SourcePositionTable::Scope pos(&source_positions, | 306 SourcePositionTable::Scope pos(&source_positions, |
351 SourcePosition::Unknown()); | 307 SourcePosition::Unknown()); |
352 Linkage linkage(info()); | 308 Linkage linkage(info()); |
353 ValueNumberingReducer vn_reducer(zone()); | 309 ValueNumberingReducer vn_reducer(zone()); |
354 SimplifiedOperatorReducer simple_reducer(&jsgraph); | 310 SimplifiedOperatorReducer simple_reducer(&jsgraph); |
355 ChangeLowering lowering(&jsgraph, &linkage); | 311 ChangeLowering lowering(&jsgraph, &linkage); |
356 MachineOperatorReducer mach_reducer(&jsgraph); | 312 MachineOperatorReducer mach_reducer(&jsgraph); |
357 GraphReducer graph_reducer(&graph); | 313 GraphReducer graph_reducer(&graph); |
358 // TODO(titzer): Figure out if we should run all reducers at once here. | 314 // TODO(titzer): Figure out if we should run all reducers at once here. |
359 graph_reducer.AddReducer(&vn_reducer); | 315 graph_reducer.AddReducer(&vn_reducer); |
360 graph_reducer.AddReducer(&simple_reducer); | 316 graph_reducer.AddReducer(&simple_reducer); |
361 graph_reducer.AddReducer(&lowering); | 317 graph_reducer.AddReducer(&lowering); |
362 graph_reducer.AddReducer(&mach_reducer); | 318 graph_reducer.AddReducer(&mach_reducer); |
363 graph_reducer.ReduceGraph(); | 319 graph_reducer.ReduceGraph(); |
364 | 320 |
365 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. | 321 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. |
366 VerifyAndPrintGraph(&graph, "Lowered changes", true); | 322 VerifyAndPrintGraph(&graph, "Lowered changes", true); |
367 } | 323 } |
368 | 324 |
369 { | 325 { |
| 326 PhaseScope phase_scope(pipeline_statistics.get(), "control reduction"); |
370 SourcePositionTable::Scope pos(&source_positions, | 327 SourcePositionTable::Scope pos(&source_positions, |
371 SourcePosition::Unknown()); | 328 SourcePosition::Unknown()); |
372 PhaseStats control_reducer_stats( | |
373 info(), &zone_pool, PhaseStats::CREATE_GRAPH, "control reduction"); | |
374 ZonePool::Scope zone_scope(&zone_pool); | 329 ZonePool::Scope zone_scope(&zone_pool); |
375 ControlReducer::ReduceGraph(zone_scope.zone(), &jsgraph, &common); | 330 ControlReducer::ReduceGraph(zone_scope.zone(), &jsgraph, &common); |
376 | 331 |
377 VerifyAndPrintGraph(&graph, "Control reduced"); | 332 VerifyAndPrintGraph(&graph, "Control reduced"); |
378 } | 333 } |
379 } | 334 } |
380 | 335 |
381 { | 336 { |
382 // Lower any remaining generic JSOperators. | 337 // Lower any remaining generic JSOperators. |
383 PhaseStats lowering_stats(info(), &zone_pool, PhaseStats::CREATE_GRAPH, | 338 PhaseScope phase_scope(pipeline_statistics.get(), "generic lowering"); |
384 "generic lowering"); | |
385 SourcePositionTable::Scope pos(&source_positions, | 339 SourcePositionTable::Scope pos(&source_positions, |
386 SourcePosition::Unknown()); | 340 SourcePosition::Unknown()); |
387 JSGenericLowering lowering(info(), &jsgraph); | 341 JSGenericLowering lowering(info(), &jsgraph); |
388 GraphReducer graph_reducer(&graph); | 342 GraphReducer graph_reducer(&graph); |
389 graph_reducer.AddReducer(&lowering); | 343 graph_reducer.AddReducer(&lowering); |
390 graph_reducer.ReduceGraph(); | 344 graph_reducer.ReduceGraph(); |
391 | 345 |
392 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. | 346 // TODO(jarin, rossberg): Remove UNTYPED once machine typing works. |
393 VerifyAndPrintGraph(&graph, "Lowered generic", true); | 347 VerifyAndPrintGraph(&graph, "Lowered generic", true); |
394 } | 348 } |
395 | 349 |
| 350 if (!pipeline_statistics.is_empty()) { |
| 351 pipeline_statistics->BeginPhaseKind("code generation"); |
| 352 } |
| 353 |
396 source_positions.RemoveDecorator(); | 354 source_positions.RemoveDecorator(); |
397 | 355 |
| 356 Schedule* schedule; |
| 357 { |
| 358 PhaseScope phase_scope(pipeline_statistics.get(), "scheduling"); |
| 359 // Compute a schedule. |
| 360 schedule = ComputeSchedule(&zone_pool, &graph); |
| 361 } |
| 362 |
398 Handle<Code> code = Handle<Code>::null(); | 363 Handle<Code> code = Handle<Code>::null(); |
399 { | 364 { |
400 // Compute a schedule. | |
401 Schedule* schedule = ComputeSchedule(&zone_pool, &graph); | |
402 // Generate optimized code. | 365 // Generate optimized code. |
403 PhaseStats codegen_stats(info(), &zone_pool, PhaseStats::CODEGEN, | |
404 "codegen"); | |
405 Linkage linkage(info()); | 366 Linkage linkage(info()); |
406 code = | 367 code = GenerateCode(pipeline_statistics.get(), &zone_pool, &linkage, &graph, |
407 GenerateCode(&zone_pool, &linkage, &graph, schedule, &source_positions); | 368 schedule, &source_positions); |
408 info()->SetCode(code); | 369 info()->SetCode(code); |
409 } | 370 } |
410 | 371 |
411 // Print optimized code. | 372 // Print optimized code. |
412 v8::internal::CodeGenerator::PrintCode(code, info()); | 373 v8::internal::CodeGenerator::PrintCode(code, info()); |
413 | 374 |
414 if (FLAG_trace_turbo) { | 375 if (FLAG_trace_turbo) { |
415 OFStream os(stdout); | 376 OFStream os(stdout); |
416 os << "--------------------------------------------------\n" | 377 os << "--------------------------------------------------\n" |
417 << "Finished compiling method " | 378 << "Finished compiling method " |
418 << info()->function()->debug_name()->ToCString().get() | 379 << info()->function()->debug_name()->ToCString().get() |
419 << " using Turbofan" << std::endl; | 380 << " using Turbofan" << std::endl; |
420 } | 381 } |
421 | 382 |
422 return code; | 383 return code; |
423 } | 384 } |
424 | 385 |
425 | 386 |
426 Schedule* Pipeline::ComputeSchedule(ZonePool* zone_pool, Graph* graph) { | 387 Schedule* Pipeline::ComputeSchedule(ZonePool* zone_pool, Graph* graph) { |
427 PhaseStats schedule_stats(info(), zone_pool, PhaseStats::CODEGEN, | |
428 "scheduling"); | |
429 Schedule* schedule = Scheduler::ComputeSchedule(zone_pool, graph); | 388 Schedule* schedule = Scheduler::ComputeSchedule(zone_pool, graph); |
430 TraceSchedule(schedule); | 389 TraceSchedule(schedule); |
431 if (VerifyGraphs()) ScheduleVerifier::Run(schedule); | 390 if (VerifyGraphs()) ScheduleVerifier::Run(schedule); |
432 return schedule; | 391 return schedule; |
433 } | 392 } |
434 | 393 |
435 | 394 |
436 Handle<Code> Pipeline::GenerateCodeForMachineGraph(Linkage* linkage, | 395 Handle<Code> Pipeline::GenerateCodeForMachineGraph(Linkage* linkage, |
437 Graph* graph, | 396 Graph* graph, |
438 Schedule* schedule) { | 397 Schedule* schedule) { |
439 ZonePool zone_pool(isolate()); | 398 ZonePool zone_pool(isolate()); |
440 CHECK(SupportedBackend()); | 399 CHECK(SupportedBackend()); |
441 if (schedule == NULL) { | 400 if (schedule == NULL) { |
442 // TODO(rossberg): Should this really be untyped? | 401 // TODO(rossberg): Should this really be untyped? |
443 VerifyAndPrintGraph(graph, "Machine", true); | 402 VerifyAndPrintGraph(graph, "Machine", true); |
444 schedule = ComputeSchedule(&zone_pool, graph); | 403 schedule = ComputeSchedule(&zone_pool, graph); |
445 } | 404 } |
446 TraceSchedule(schedule); | 405 TraceSchedule(schedule); |
447 | 406 |
448 SourcePositionTable source_positions(graph); | 407 SourcePositionTable source_positions(graph); |
449 Handle<Code> code = | 408 Handle<Code> code = GenerateCode(NULL, &zone_pool, linkage, graph, schedule, |
450 GenerateCode(&zone_pool, linkage, graph, schedule, &source_positions); | 409 &source_positions); |
451 #if ENABLE_DISASSEMBLER | 410 #if ENABLE_DISASSEMBLER |
452 if (!code.is_null() && FLAG_print_opt_code) { | 411 if (!code.is_null() && FLAG_print_opt_code) { |
453 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer()); | 412 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer()); |
454 OFStream os(tracing_scope.file()); | 413 OFStream os(tracing_scope.file()); |
455 code->Disassemble("test code", os); | 414 code->Disassemble("test code", os); |
456 } | 415 } |
457 #endif | 416 #endif |
458 return code; | 417 return code; |
459 } | 418 } |
460 | 419 |
461 | 420 |
462 Handle<Code> Pipeline::GenerateCode(ZonePool* zone_pool, Linkage* linkage, | 421 Handle<Code> Pipeline::GenerateCode(PipelineStatistics* pipeline_statistics, |
| 422 ZonePool* zone_pool, Linkage* linkage, |
463 Graph* graph, Schedule* schedule, | 423 Graph* graph, Schedule* schedule, |
464 SourcePositionTable* source_positions) { | 424 SourcePositionTable* source_positions) { |
465 DCHECK_NOT_NULL(graph); | 425 DCHECK_NOT_NULL(graph); |
466 DCHECK_NOT_NULL(linkage); | 426 DCHECK_NOT_NULL(linkage); |
467 DCHECK_NOT_NULL(schedule); | 427 DCHECK_NOT_NULL(schedule); |
468 CHECK(SupportedBackend()); | 428 CHECK(SupportedBackend()); |
469 | 429 |
470 BasicBlockProfiler::Data* profiler_data = NULL; | 430 BasicBlockProfiler::Data* profiler_data = NULL; |
471 if (FLAG_turbo_profiling) { | 431 if (FLAG_turbo_profiling) { |
472 profiler_data = BasicBlockInstrumentor::Instrument(info_, graph, schedule); | 432 profiler_data = BasicBlockInstrumentor::Instrument(info_, graph, schedule); |
473 } | 433 } |
474 | 434 |
475 Zone* instruction_zone = schedule->zone(); | 435 Zone* instruction_zone = schedule->zone(); |
476 InstructionSequence sequence(instruction_zone, graph, schedule); | 436 InstructionSequence sequence(instruction_zone, graph, schedule); |
477 | 437 |
478 // Select and schedule instructions covering the scheduled graph. | 438 // Select and schedule instructions covering the scheduled graph. |
479 { | 439 { |
| 440 PhaseScope phase_scope(pipeline_statistics, "select instructions"); |
480 ZonePool::Scope zone_scope(zone_pool); | 441 ZonePool::Scope zone_scope(zone_pool); |
481 InstructionSelector selector(zone_scope.zone(), linkage, &sequence, | 442 InstructionSelector selector(zone_scope.zone(), linkage, &sequence, |
482 schedule, source_positions); | 443 schedule, source_positions); |
483 selector.SelectInstructions(); | 444 selector.SelectInstructions(); |
484 } | 445 } |
485 | 446 |
486 if (FLAG_trace_turbo) { | 447 if (FLAG_trace_turbo) { |
487 OFStream os(stdout); | 448 OFStream os(stdout); |
488 os << "----- Instruction sequence before register allocation -----\n" | 449 os << "----- Instruction sequence before register allocation -----\n" |
489 << sequence; | 450 << sequence; |
490 PrintScheduleAndInstructions("CodeGen", schedule, source_positions, | 451 PrintScheduleAndInstructions("CodeGen", schedule, source_positions, |
491 &sequence); | 452 &sequence); |
492 } | 453 } |
493 | 454 |
494 // Allocate registers. | 455 // Allocate registers. |
495 Frame frame; | 456 Frame frame; |
496 { | 457 { |
497 int node_count = graph->NodeCount(); | 458 int node_count = graph->NodeCount(); |
498 if (node_count > UnallocatedOperand::kMaxVirtualRegisters) { | 459 if (node_count > UnallocatedOperand::kMaxVirtualRegisters) { |
499 linkage->info()->AbortOptimization(kNotEnoughVirtualRegistersForValues); | 460 linkage->info()->AbortOptimization(kNotEnoughVirtualRegistersForValues); |
500 return Handle<Code>::null(); | 461 return Handle<Code>::null(); |
501 } | 462 } |
502 ZonePool::Scope zone_scope(zone_pool); | 463 ZonePool::Scope zone_scope(zone_pool); |
503 RegisterAllocator allocator(zone_scope.zone(), &frame, linkage->info(), | 464 RegisterAllocator allocator(zone_scope.zone(), &frame, linkage->info(), |
504 &sequence); | 465 &sequence); |
505 if (!allocator.Allocate(zone_pool)) { | 466 if (!allocator.Allocate(pipeline_statistics)) { |
506 linkage->info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc); | 467 linkage->info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc); |
507 return Handle<Code>::null(); | 468 return Handle<Code>::null(); |
508 } | 469 } |
509 if (FLAG_trace_turbo) { | 470 if (FLAG_trace_turbo) { |
510 PrintAllocator("CodeGen", &allocator); | 471 PrintAllocator("CodeGen", &allocator); |
511 } | 472 } |
512 } | 473 } |
513 | 474 |
514 if (FLAG_trace_turbo) { | 475 if (FLAG_trace_turbo) { |
515 OFStream os(stdout); | 476 OFStream os(stdout); |
516 os << "----- Instruction sequence after register allocation -----\n" | 477 os << "----- Instruction sequence after register allocation -----\n" |
517 << sequence; | 478 << sequence; |
518 } | 479 } |
519 | 480 |
520 // Generate native sequence. | 481 // Generate native sequence. |
521 CodeGenerator generator(&frame, linkage, &sequence); | 482 Handle<Code> code; |
522 Handle<Code> code = generator.GenerateCode(); | 483 { |
| 484 PhaseScope phase_scope(pipeline_statistics, "generate code"); |
| 485 CodeGenerator generator(&frame, linkage, &sequence); |
| 486 code = generator.GenerateCode(); |
| 487 } |
523 if (profiler_data != NULL) { | 488 if (profiler_data != NULL) { |
524 #if ENABLE_DISASSEMBLER | 489 #if ENABLE_DISASSEMBLER |
525 std::ostringstream os; | 490 std::ostringstream os; |
526 code->Disassemble(NULL, os); | 491 code->Disassemble(NULL, os); |
527 profiler_data->SetCode(&os); | 492 profiler_data->SetCode(&os); |
528 #endif | 493 #endif |
529 } | 494 } |
530 return code; | 495 return code; |
531 } | 496 } |
532 | 497 |
533 | 498 |
534 void Pipeline::SetUp() { | 499 void Pipeline::SetUp() { |
535 InstructionOperand::SetUpCaches(); | 500 InstructionOperand::SetUpCaches(); |
536 } | 501 } |
537 | 502 |
538 | 503 |
539 void Pipeline::TearDown() { | 504 void Pipeline::TearDown() { |
540 InstructionOperand::TearDownCaches(); | 505 InstructionOperand::TearDownCaches(); |
541 } | 506 } |
542 | 507 |
543 } // namespace compiler | 508 } // namespace compiler |
544 } // namespace internal | 509 } // namespace internal |
545 } // namespace v8 | 510 } // namespace v8 |
OLD | NEW |