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