Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(74)

Unified Diff: src/compiler/pipeline.cc

Issue 426233002: Land the Fan (disabled) (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Review feedback, rebase and "git cl format" Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/pipeline.h ('k') | src/compiler/raw-machine-assembler.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/pipeline.cc
diff --git a/src/compiler/pipeline.cc b/src/compiler/pipeline.cc
new file mode 100644
index 0000000000000000000000000000000000000000..25f0063972b09708d00fad862b337e2f6d7f50a5
--- /dev/null
+++ b/src/compiler/pipeline.cc
@@ -0,0 +1,290 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// 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 "src/base/platform/elapsed-timer.h"
+#include "src/compiler/ast-graph-builder.h"
+#include "src/compiler/code-generator.h"
+#include "src/compiler/graph-replay.h"
+#include "src/compiler/graph-visualizer.h"
+#include "src/compiler/instruction-selector.h"
+#include "src/compiler/js-context-specialization.h"
+#include "src/compiler/js-generic-lowering.h"
+#include "src/compiler/js-typed-lowering.h"
+#include "src/compiler/register-allocator.h"
+#include "src/compiler/schedule.h"
+#include "src/compiler/scheduler.h"
+#include "src/compiler/simplified-lowering.h"
+#include "src/compiler/typer.h"
+#include "src/compiler/verifier.h"
+#include "src/hydrogen.h"
+#include "src/ostreams.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class PhaseStats {
+ public:
+ enum PhaseKind { CREATE_GRAPH, OPTIMIZATION, CODEGEN };
+
+ PhaseStats(CompilationInfo* info, PhaseKind kind, const char* name)
+ : info_(info),
+ kind_(kind),
+ name_(name),
+ size_(info->zone()->allocation_size()) {
+ if (FLAG_turbo_stats) {
+ timer_.Start();
+ }
+ }
+
+ ~PhaseStats() {
+ if (FLAG_turbo_stats) {
+ base::TimeDelta delta = timer_.Elapsed();
+ size_t bytes = info_->zone()->allocation_size() - size_;
+ HStatistics* stats = info_->isolate()->GetTStatistics();
+ stats->SaveTiming(name_, delta, 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_;
+ PhaseKind kind_;
+ const char* name_;
+ size_t size_;
+ base::ElapsedTimer timer_;
+};
+
+
+void Pipeline::VerifyAndPrintGraph(Graph* graph, const char* phase) {
+ if (FLAG_trace_turbo) {
+ OFStream os(stdout);
+ os << "-- " << phase << " graph -----------------------------------\n"
+ << AsDOT(*graph);
+ }
+ if (VerifyGraphs()) Verifier::Run(graph);
+}
+
+
+class AstGraphBuilderWithPositions : public AstGraphBuilder {
+ public:
+ explicit AstGraphBuilderWithPositions(CompilationInfo* info, JSGraph* jsgraph,
+ SourcePositionTable* source_positions)
+ : AstGraphBuilder(info, jsgraph, source_positions) {}
+
+#define DEF_VISIT(type) \
+ virtual void Visit##type(type* node) V8_OVERRIDE { \
+ SourcePositionTable::Scope pos(source_positions(), \
+ SourcePosition(node->position())); \
+ AstGraphBuilder::Visit##type(node); \
+ }
+ AST_NODE_LIST(DEF_VISIT)
+#undef DEF_VISIT
+};
+
+
+static void TraceSchedule(Schedule* schedule) {
+ if (!FLAG_trace_turbo) return;
+ OFStream os(stdout);
+ os << "-- Schedule --------------------------------------\n" << *schedule;
+}
+
+
+Handle<Code> Pipeline::GenerateCode() {
+ if (FLAG_turbo_stats) isolate()->GetTStatistics()->Initialize(info_);
+
+ if (FLAG_trace_turbo) {
+ OFStream os(stdout);
+ os << "---------------------------------------------------\n"
+ << "Begin compiling method "
+ << info()->function()->debug_name()->ToCString().get()
+ << " using Turbofan" << endl;
+ }
+
+ // Build the graph.
+ Graph graph(zone());
+ SourcePositionTable source_positions(&graph);
+ source_positions.AddDecorator();
+ // TODO(turbofan): there is no need to type anything during initial graph
+ // construction. This is currently only needed for the node cache, which the
+ // typer could sweep over later.
+ Typer typer(zone());
+ CommonOperatorBuilder common(zone());
+ JSGraph jsgraph(&graph, &common, &typer);
+ Node* context_node;
+ {
+ PhaseStats graph_builder_stats(info(), PhaseStats::CREATE_GRAPH,
+ "graph builder");
+ AstGraphBuilderWithPositions graph_builder(info(), &jsgraph,
+ &source_positions);
+ graph_builder.CreateGraph();
+ context_node = graph_builder.GetFunctionContext();
+ }
+
+ VerifyAndPrintGraph(&graph, "Initial untyped");
+
+ if (FLAG_context_specialization) {
+ SourcePositionTable::Scope pos_(&source_positions,
+ SourcePosition::Unknown());
+ // Specialize the code to the context as aggressively as possible.
+ JSContextSpecializer spec(info(), &jsgraph, context_node);
+ spec.SpecializeToContext();
+ VerifyAndPrintGraph(&graph, "Context specialized");
+ }
+
+ // Print a replay of the initial graph.
+ if (FLAG_print_turbo_replay) {
+ GraphReplayPrinter::PrintReplay(&graph);
+ }
+
+ if (FLAG_turbo_types) {
+ {
+ // Type the graph.
+ PhaseStats typer_stats(info(), PhaseStats::CREATE_GRAPH, "typer");
+ typer.Run(&graph, info()->context());
+ }
+ // All new nodes must be typed.
+ typer.DecorateGraph(&graph);
+ {
+ // Lower JSOperators where we can determine types.
+ PhaseStats lowering_stats(info(), PhaseStats::CREATE_GRAPH,
+ "typed lowering");
+ JSTypedLowering lowering(&jsgraph, &source_positions);
+ lowering.LowerAllNodes();
+
+ VerifyAndPrintGraph(&graph, "Lowered typed");
+ }
+ }
+
+ {
+ // Lower any remaining generic JSOperators.
+ PhaseStats lowering_stats(info(), PhaseStats::CREATE_GRAPH,
+ "generic lowering");
+ MachineOperatorBuilder machine(zone());
+ JSGenericLowering lowering(info(), &jsgraph, &machine, &source_positions);
+ lowering.LowerAllNodes();
+ }
+
+ // Compute a schedule.
+ Schedule* schedule = ComputeSchedule(&graph);
+ TraceSchedule(schedule);
+
+ Handle<Code> code = Handle<Code>::null();
+ if (SupportedTarget()) {
+ {
+ // Generate optimized code.
+ PhaseStats codegen_stats(info(), PhaseStats::CODEGEN, "codegen");
+ Linkage linkage(info());
+ code = GenerateCode(&linkage, &graph, schedule, &source_positions);
+ info()->SetCode(code);
+ }
+ // Print optimized code.
+ v8::internal::CodeGenerator::PrintCode(code, info());
+ }
+
+ if (FLAG_trace_turbo) {
+ OFStream os(stdout);
+ os << "--------------------------------------------------\n"
+ << "Finished compiling method "
+ << info()->function()->debug_name()->ToCString().get()
+ << " using Turbofan" << endl;
+ }
+
+ return code;
+}
+
+
+Schedule* Pipeline::ComputeSchedule(Graph* graph) {
+ Scheduler scheduler(zone());
+ PhaseStats schedule_stats(info(), PhaseStats::CODEGEN, "scheduling");
+ return scheduler.NewSchedule(graph);
+}
+
+
+Handle<Code> Pipeline::GenerateCodeForMachineGraph(Linkage* linkage,
+ Graph* graph,
+ Schedule* schedule) {
+ CHECK(SupportedTarget());
+ if (schedule == NULL) {
+ VerifyAndPrintGraph(graph, "Machine");
+ schedule = ComputeSchedule(graph);
+ }
+ TraceSchedule(schedule);
+
+ SourcePositionTable source_positions(graph);
+ Handle<Code> code = GenerateCode(linkage, graph, schedule, &source_positions);
+#if ENABLE_DISASSEMBLER
+ if (!code.is_null() && FLAG_print_opt_code) {
+ CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer());
+ OFStream os(tracing_scope.file());
+ code->Disassemble("test code", os);
+ }
+#endif
+ return code;
+}
+
+
+Handle<Code> Pipeline::GenerateCode(Linkage* linkage, Graph* graph,
+ Schedule* schedule,
+ SourcePositionTable* source_positions) {
+ ASSERT_NOT_NULL(graph);
+ ASSERT_NOT_NULL(linkage);
+ ASSERT_NOT_NULL(schedule);
+ ASSERT(SupportedTarget());
+
+ InstructionSequence sequence(linkage, graph, schedule);
+
+ // Select and schedule instructions covering the scheduled graph.
+ {
+ InstructionSelector selector(&sequence, source_positions);
+ selector.SelectInstructions();
+ }
+
+ if (FLAG_trace_turbo) {
+ OFStream os(stdout);
+ os << "----- Instruction sequence before register allocation -----\n"
+ << sequence;
+ }
+
+ // Allocate registers.
+ {
+ int node_count = graph->NodeCount();
+ if (node_count > UnallocatedOperand::kMaxVirtualRegisters) {
+ linkage->info()->set_bailout_reason(kNotEnoughVirtualRegistersForValues);
+ return Handle<Code>::null();
+ }
+ RegisterAllocator allocator(&sequence);
+ if (!allocator.Allocate()) {
+ linkage->info()->set_bailout_reason(kNotEnoughVirtualRegistersRegalloc);
+ return Handle<Code>::null();
+ }
+ }
+
+ if (FLAG_trace_turbo) {
+ OFStream os(stdout);
+ os << "----- Instruction sequence after register allocation -----\n"
+ << sequence;
+ }
+
+ // Generate native sequence.
+ CodeGenerator generator(&sequence);
+ return generator.GenerateCode();
+}
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8
« no previous file with comments | « src/compiler/pipeline.h ('k') | src/compiler/raw-machine-assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698