Index: src/compiler/pipeline.cc |
diff --git a/src/compiler/pipeline.cc b/src/compiler/pipeline.cc |
index 438f10459524b33113a439c942e0434097f1fdc2..609de0670b16d6795c323efae90afa8f3ff7b7db 100644 |
--- a/src/compiler/pipeline.cc |
+++ b/src/compiler/pipeline.cc |
@@ -2,8 +2,6 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-#include "src/compiler/pipeline.h" |
- |
#include <sstream> |
#include "src/base/platform/elapsed-timer.h" |
@@ -22,6 +20,8 @@ |
#include "src/compiler/js-typed-lowering.h" |
#include "src/compiler/machine-operator-reducer.h" |
#include "src/compiler/phi-reducer.h" |
+#include "src/compiler/pipeline.h" |
+#include "src/compiler/pipeline-statistics.h" |
#include "src/compiler/register-allocator.h" |
#include "src/compiler/schedule.h" |
#include "src/compiler/scheduler.h" |
@@ -31,7 +31,6 @@ |
#include "src/compiler/value-numbering-reducer.h" |
#include "src/compiler/verifier.h" |
#include "src/compiler/zone-pool.h" |
-#include "src/hydrogen.h" |
#include "src/ostreams.h" |
#include "src/utils.h" |
@@ -39,55 +38,6 @@ namespace v8 { |
namespace internal { |
namespace compiler { |
-class PhaseStats { |
- public: |
- enum PhaseKind { CREATE_GRAPH, OPTIMIZATION, CODEGEN }; |
- |
- PhaseStats(CompilationInfo* info, ZonePool* zone_pool, PhaseKind kind, |
- const char* name) |
- : info_(info), |
- stats_scope_(zone_pool), |
- kind_(kind), |
- name_(name), |
- size_(0) { |
- if (FLAG_turbo_stats) { |
- timer_.Start(); |
- size_ = info_->zone()->allocation_size(); |
- } |
- } |
- |
- ~PhaseStats() { |
- if (FLAG_turbo_stats) { |
- base::TimeDelta delta = timer_.Elapsed(); |
- size_t bytes = info_->zone()->allocation_size() + |
- stats_scope_.GetMaxAllocatedBytes() - size_; |
- HStatistics* stats = info_->isolate()->GetTStatistics(); |
- stats->SaveTiming(name_, delta, static_cast<int>(bytes)); |
- |
- switch (kind_) { |
- case CREATE_GRAPH: |
- stats->IncrementCreateGraph(delta); |
- break; |
- case OPTIMIZATION: |
- stats->IncrementOptimizeGraph(delta); |
- break; |
- case CODEGEN: |
- stats->IncrementGenerateCode(delta); |
- break; |
- } |
- } |
- } |
- |
- private: |
- CompilationInfo* info_; |
- ZonePool::StatsScope stats_scope_; |
- PhaseKind kind_; |
- const char* name_; |
- size_t size_; |
- base::ElapsedTimer timer_; |
-}; |
- |
- |
static inline bool VerifyGraphs() { |
#ifdef DEBUG |
return true; |
@@ -226,7 +176,13 @@ Handle<Code> Pipeline::GenerateCode() { |
return Handle<Code>::null(); |
} |
- if (FLAG_turbo_stats) isolate()->GetTStatistics()->Initialize(info_); |
+ ZonePool zone_pool(isolate()); |
+ |
+ SmartPointer<PipelineStatistics> pipeline_statistics; |
+ if (FLAG_turbo_stats) { |
+ pipeline_statistics.Reset(new PipelineStatistics(info(), &zone_pool)); |
+ pipeline_statistics->BeginPhaseKind("create graph"); |
+ } |
if (FLAG_trace_turbo) { |
OFStream os(stdout); |
@@ -237,8 +193,6 @@ Handle<Code> Pipeline::GenerateCode() { |
PrintCompilationStart(); |
} |
- ZonePool zone_pool(isolate()); |
- |
// Build the graph. |
Graph graph(zone()); |
SourcePositionTable source_positions(&graph); |
@@ -253,8 +207,7 @@ Handle<Code> Pipeline::GenerateCode() { |
JSGraph jsgraph(&graph, &common, &javascript, &machine); |
Node* context_node; |
{ |
- PhaseStats graph_builder_stats(info(), &zone_pool, PhaseStats::CREATE_GRAPH, |
- "graph builder"); |
+ PhaseScope phase_scope(pipeline_statistics.get(), "graph builder"); |
ZonePool::Scope zone_scope(&zone_pool); |
AstGraphBuilderWithPositions graph_builder(zone_scope.zone(), info(), |
&jsgraph, &source_positions); |
@@ -262,8 +215,7 @@ Handle<Code> Pipeline::GenerateCode() { |
context_node = graph_builder.GetFunctionContext(); |
} |
{ |
- PhaseStats phi_reducer_stats(info(), &zone_pool, PhaseStats::CREATE_GRAPH, |
- "phi reduction"); |
+ PhaseScope phase_scope(pipeline_statistics.get(), "phi reduction"); |
PhiReducer phi_reducer; |
GraphReducer graph_reducer(&graph); |
graph_reducer.AddReducer(&phi_reducer); |
@@ -285,6 +237,7 @@ Handle<Code> Pipeline::GenerateCode() { |
} |
if (info()->is_inlining_enabled()) { |
+ PhaseScope phase_scope(pipeline_statistics.get(), "inlining"); |
SourcePositionTable::Scope pos(&source_positions, |
SourcePosition::Unknown()); |
ZonePool::Scope zone_scope(&zone_pool); |
@@ -304,15 +257,20 @@ Handle<Code> Pipeline::GenerateCode() { |
if (info()->is_typing_enabled()) { |
{ |
// Type the graph. |
- PhaseStats typer_stats(info(), &zone_pool, PhaseStats::CREATE_GRAPH, |
- "typer"); |
+ PhaseScope phase_scope(pipeline_statistics.get(), "typer"); |
typer.Run(); |
VerifyAndPrintGraph(&graph, "Typed"); |
} |
+ } |
+ |
+ if (!pipeline_statistics.is_empty()) { |
+ pipeline_statistics->BeginPhaseKind("lowering"); |
+ } |
+ |
+ if (info()->is_typing_enabled()) { |
{ |
// Lower JSOperators where we can determine types. |
- PhaseStats lowering_stats(info(), &zone_pool, PhaseStats::CREATE_GRAPH, |
- "typed lowering"); |
+ PhaseScope phase_scope(pipeline_statistics.get(), "typed lowering"); |
SourcePositionTable::Scope pos(&source_positions, |
SourcePosition::Unknown()); |
ValueNumberingReducer vn_reducer(zone()); |
@@ -328,8 +286,7 @@ Handle<Code> Pipeline::GenerateCode() { |
} |
{ |
// Lower simplified operators and insert changes. |
- PhaseStats lowering_stats(info(), &zone_pool, PhaseStats::CREATE_GRAPH, |
- "simplified lowering"); |
+ PhaseScope phase_scope(pipeline_statistics.get(), "simplified lowering"); |
SourcePositionTable::Scope pos(&source_positions, |
SourcePosition::Unknown()); |
SimplifiedLowering lowering(&jsgraph); |
@@ -345,8 +302,7 @@ Handle<Code> Pipeline::GenerateCode() { |
} |
{ |
// Lower changes that have been inserted before. |
- PhaseStats lowering_stats(info(), &zone_pool, PhaseStats::OPTIMIZATION, |
- "change lowering"); |
+ PhaseScope phase_scope(pipeline_statistics.get(), "change lowering"); |
SourcePositionTable::Scope pos(&source_positions, |
SourcePosition::Unknown()); |
Linkage linkage(info()); |
@@ -367,10 +323,9 @@ Handle<Code> Pipeline::GenerateCode() { |
} |
{ |
+ PhaseScope phase_scope(pipeline_statistics.get(), "control reduction"); |
SourcePositionTable::Scope pos(&source_positions, |
SourcePosition::Unknown()); |
- PhaseStats control_reducer_stats( |
- info(), &zone_pool, PhaseStats::CREATE_GRAPH, "control reduction"); |
ZonePool::Scope zone_scope(&zone_pool); |
ControlReducer::ReduceGraph(zone_scope.zone(), &jsgraph, &common); |
@@ -380,8 +335,7 @@ Handle<Code> Pipeline::GenerateCode() { |
{ |
// Lower any remaining generic JSOperators. |
- PhaseStats lowering_stats(info(), &zone_pool, PhaseStats::CREATE_GRAPH, |
- "generic lowering"); |
+ PhaseScope phase_scope(pipeline_statistics.get(), "generic lowering"); |
SourcePositionTable::Scope pos(&source_positions, |
SourcePosition::Unknown()); |
JSGenericLowering lowering(info(), &jsgraph); |
@@ -393,18 +347,25 @@ Handle<Code> Pipeline::GenerateCode() { |
VerifyAndPrintGraph(&graph, "Lowered generic", true); |
} |
+ if (!pipeline_statistics.is_empty()) { |
+ pipeline_statistics->BeginPhaseKind("code generation"); |
+ } |
+ |
source_positions.RemoveDecorator(); |
- Handle<Code> code = Handle<Code>::null(); |
+ Schedule* schedule; |
{ |
+ PhaseScope phase_scope(pipeline_statistics.get(), "scheduling"); |
// Compute a schedule. |
- Schedule* schedule = ComputeSchedule(&zone_pool, &graph); |
+ schedule = ComputeSchedule(&zone_pool, &graph); |
+ } |
+ |
+ Handle<Code> code = Handle<Code>::null(); |
+ { |
// Generate optimized code. |
- PhaseStats codegen_stats(info(), &zone_pool, PhaseStats::CODEGEN, |
- "codegen"); |
Linkage linkage(info()); |
- code = |
- GenerateCode(&zone_pool, &linkage, &graph, schedule, &source_positions); |
+ code = GenerateCode(pipeline_statistics.get(), &zone_pool, &linkage, &graph, |
+ schedule, &source_positions); |
info()->SetCode(code); |
} |
@@ -424,8 +385,6 @@ Handle<Code> Pipeline::GenerateCode() { |
Schedule* Pipeline::ComputeSchedule(ZonePool* zone_pool, Graph* graph) { |
- PhaseStats schedule_stats(info(), zone_pool, PhaseStats::CODEGEN, |
- "scheduling"); |
Schedule* schedule = Scheduler::ComputeSchedule(zone_pool, graph); |
TraceSchedule(schedule); |
if (VerifyGraphs()) ScheduleVerifier::Run(schedule); |
@@ -446,8 +405,8 @@ Handle<Code> Pipeline::GenerateCodeForMachineGraph(Linkage* linkage, |
TraceSchedule(schedule); |
SourcePositionTable source_positions(graph); |
- Handle<Code> code = |
- GenerateCode(&zone_pool, linkage, graph, schedule, &source_positions); |
+ Handle<Code> code = GenerateCode(NULL, &zone_pool, linkage, graph, schedule, |
+ &source_positions); |
#if ENABLE_DISASSEMBLER |
if (!code.is_null() && FLAG_print_opt_code) { |
CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer()); |
@@ -459,7 +418,8 @@ Handle<Code> Pipeline::GenerateCodeForMachineGraph(Linkage* linkage, |
} |
-Handle<Code> Pipeline::GenerateCode(ZonePool* zone_pool, Linkage* linkage, |
+Handle<Code> Pipeline::GenerateCode(PipelineStatistics* pipeline_statistics, |
+ ZonePool* zone_pool, Linkage* linkage, |
Graph* graph, Schedule* schedule, |
SourcePositionTable* source_positions) { |
DCHECK_NOT_NULL(graph); |
@@ -477,6 +437,7 @@ Handle<Code> Pipeline::GenerateCode(ZonePool* zone_pool, Linkage* linkage, |
// Select and schedule instructions covering the scheduled graph. |
{ |
+ PhaseScope phase_scope(pipeline_statistics, "select instructions"); |
ZonePool::Scope zone_scope(zone_pool); |
InstructionSelector selector(zone_scope.zone(), linkage, &sequence, |
schedule, source_positions); |
@@ -502,7 +463,7 @@ Handle<Code> Pipeline::GenerateCode(ZonePool* zone_pool, Linkage* linkage, |
ZonePool::Scope zone_scope(zone_pool); |
RegisterAllocator allocator(zone_scope.zone(), &frame, linkage->info(), |
&sequence); |
- if (!allocator.Allocate(zone_pool)) { |
+ if (!allocator.Allocate(pipeline_statistics)) { |
linkage->info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc); |
return Handle<Code>::null(); |
} |
@@ -518,8 +479,12 @@ Handle<Code> Pipeline::GenerateCode(ZonePool* zone_pool, Linkage* linkage, |
} |
// Generate native sequence. |
- CodeGenerator generator(&frame, linkage, &sequence); |
- Handle<Code> code = generator.GenerateCode(); |
+ Handle<Code> code; |
+ { |
+ PhaseScope phase_scope(pipeline_statistics, "generate code"); |
+ CodeGenerator generator(&frame, linkage, &sequence); |
+ code = generator.GenerateCode(); |
+ } |
if (profiler_data != NULL) { |
#if ENABLE_DISASSEMBLER |
std::ostringstream os; |