| 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 |