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

Side by Side 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, 4 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/compiler/pipeline.h ('k') | src/compiler/raw-machine-assembler.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "src/compiler/pipeline.h"
6
7 #include "src/base/platform/elapsed-timer.h"
8 #include "src/compiler/ast-graph-builder.h"
9 #include "src/compiler/code-generator.h"
10 #include "src/compiler/graph-replay.h"
11 #include "src/compiler/graph-visualizer.h"
12 #include "src/compiler/instruction-selector.h"
13 #include "src/compiler/js-context-specialization.h"
14 #include "src/compiler/js-generic-lowering.h"
15 #include "src/compiler/js-typed-lowering.h"
16 #include "src/compiler/register-allocator.h"
17 #include "src/compiler/schedule.h"
18 #include "src/compiler/scheduler.h"
19 #include "src/compiler/simplified-lowering.h"
20 #include "src/compiler/typer.h"
21 #include "src/compiler/verifier.h"
22 #include "src/hydrogen.h"
23 #include "src/ostreams.h"
24
25 namespace v8 {
26 namespace internal {
27 namespace compiler {
28
29 class PhaseStats {
30 public:
31 enum PhaseKind { CREATE_GRAPH, OPTIMIZATION, CODEGEN };
32
33 PhaseStats(CompilationInfo* info, PhaseKind kind, const char* name)
34 : info_(info),
35 kind_(kind),
36 name_(name),
37 size_(info->zone()->allocation_size()) {
38 if (FLAG_turbo_stats) {
39 timer_.Start();
40 }
41 }
42
43 ~PhaseStats() {
44 if (FLAG_turbo_stats) {
45 base::TimeDelta delta = timer_.Elapsed();
46 size_t bytes = info_->zone()->allocation_size() - size_;
47 HStatistics* stats = info_->isolate()->GetTStatistics();
48 stats->SaveTiming(name_, delta, bytes);
49
50 switch (kind_) {
51 case CREATE_GRAPH:
52 stats->IncrementCreateGraph(delta);
53 break;
54 case OPTIMIZATION:
55 stats->IncrementOptimizeGraph(delta);
56 break;
57 case CODEGEN:
58 stats->IncrementGenerateCode(delta);
59 break;
60 }
61 }
62 }
63
64 private:
65 CompilationInfo* info_;
66 PhaseKind kind_;
67 const char* name_;
68 size_t size_;
69 base::ElapsedTimer timer_;
70 };
71
72
73 void Pipeline::VerifyAndPrintGraph(Graph* graph, const char* phase) {
74 if (FLAG_trace_turbo) {
75 OFStream os(stdout);
76 os << "-- " << phase << " graph -----------------------------------\n"
77 << AsDOT(*graph);
78 }
79 if (VerifyGraphs()) Verifier::Run(graph);
80 }
81
82
83 class AstGraphBuilderWithPositions : public AstGraphBuilder {
84 public:
85 explicit AstGraphBuilderWithPositions(CompilationInfo* info, JSGraph* jsgraph,
86 SourcePositionTable* source_positions)
87 : AstGraphBuilder(info, jsgraph, source_positions) {}
88
89 #define DEF_VISIT(type) \
90 virtual void Visit##type(type* node) V8_OVERRIDE { \
91 SourcePositionTable::Scope pos(source_positions(), \
92 SourcePosition(node->position())); \
93 AstGraphBuilder::Visit##type(node); \
94 }
95 AST_NODE_LIST(DEF_VISIT)
96 #undef DEF_VISIT
97 };
98
99
100 static void TraceSchedule(Schedule* schedule) {
101 if (!FLAG_trace_turbo) return;
102 OFStream os(stdout);
103 os << "-- Schedule --------------------------------------\n" << *schedule;
104 }
105
106
107 Handle<Code> Pipeline::GenerateCode() {
108 if (FLAG_turbo_stats) isolate()->GetTStatistics()->Initialize(info_);
109
110 if (FLAG_trace_turbo) {
111 OFStream os(stdout);
112 os << "---------------------------------------------------\n"
113 << "Begin compiling method "
114 << info()->function()->debug_name()->ToCString().get()
115 << " using Turbofan" << endl;
116 }
117
118 // Build the graph.
119 Graph graph(zone());
120 SourcePositionTable source_positions(&graph);
121 source_positions.AddDecorator();
122 // TODO(turbofan): there is no need to type anything during initial graph
123 // construction. This is currently only needed for the node cache, which the
124 // typer could sweep over later.
125 Typer typer(zone());
126 CommonOperatorBuilder common(zone());
127 JSGraph jsgraph(&graph, &common, &typer);
128 Node* context_node;
129 {
130 PhaseStats graph_builder_stats(info(), PhaseStats::CREATE_GRAPH,
131 "graph builder");
132 AstGraphBuilderWithPositions graph_builder(info(), &jsgraph,
133 &source_positions);
134 graph_builder.CreateGraph();
135 context_node = graph_builder.GetFunctionContext();
136 }
137
138 VerifyAndPrintGraph(&graph, "Initial untyped");
139
140 if (FLAG_context_specialization) {
141 SourcePositionTable::Scope pos_(&source_positions,
142 SourcePosition::Unknown());
143 // Specialize the code to the context as aggressively as possible.
144 JSContextSpecializer spec(info(), &jsgraph, context_node);
145 spec.SpecializeToContext();
146 VerifyAndPrintGraph(&graph, "Context specialized");
147 }
148
149 // Print a replay of the initial graph.
150 if (FLAG_print_turbo_replay) {
151 GraphReplayPrinter::PrintReplay(&graph);
152 }
153
154 if (FLAG_turbo_types) {
155 {
156 // Type the graph.
157 PhaseStats typer_stats(info(), PhaseStats::CREATE_GRAPH, "typer");
158 typer.Run(&graph, info()->context());
159 }
160 // All new nodes must be typed.
161 typer.DecorateGraph(&graph);
162 {
163 // Lower JSOperators where we can determine types.
164 PhaseStats lowering_stats(info(), PhaseStats::CREATE_GRAPH,
165 "typed lowering");
166 JSTypedLowering lowering(&jsgraph, &source_positions);
167 lowering.LowerAllNodes();
168
169 VerifyAndPrintGraph(&graph, "Lowered typed");
170 }
171 }
172
173 {
174 // Lower any remaining generic JSOperators.
175 PhaseStats lowering_stats(info(), PhaseStats::CREATE_GRAPH,
176 "generic lowering");
177 MachineOperatorBuilder machine(zone());
178 JSGenericLowering lowering(info(), &jsgraph, &machine, &source_positions);
179 lowering.LowerAllNodes();
180 }
181
182 // Compute a schedule.
183 Schedule* schedule = ComputeSchedule(&graph);
184 TraceSchedule(schedule);
185
186 Handle<Code> code = Handle<Code>::null();
187 if (SupportedTarget()) {
188 {
189 // Generate optimized code.
190 PhaseStats codegen_stats(info(), PhaseStats::CODEGEN, "codegen");
191 Linkage linkage(info());
192 code = GenerateCode(&linkage, &graph, schedule, &source_positions);
193 info()->SetCode(code);
194 }
195 // Print optimized code.
196 v8::internal::CodeGenerator::PrintCode(code, info());
197 }
198
199 if (FLAG_trace_turbo) {
200 OFStream os(stdout);
201 os << "--------------------------------------------------\n"
202 << "Finished compiling method "
203 << info()->function()->debug_name()->ToCString().get()
204 << " using Turbofan" << endl;
205 }
206
207 return code;
208 }
209
210
211 Schedule* Pipeline::ComputeSchedule(Graph* graph) {
212 Scheduler scheduler(zone());
213 PhaseStats schedule_stats(info(), PhaseStats::CODEGEN, "scheduling");
214 return scheduler.NewSchedule(graph);
215 }
216
217
218 Handle<Code> Pipeline::GenerateCodeForMachineGraph(Linkage* linkage,
219 Graph* graph,
220 Schedule* schedule) {
221 CHECK(SupportedTarget());
222 if (schedule == NULL) {
223 VerifyAndPrintGraph(graph, "Machine");
224 schedule = ComputeSchedule(graph);
225 }
226 TraceSchedule(schedule);
227
228 SourcePositionTable source_positions(graph);
229 Handle<Code> code = GenerateCode(linkage, graph, schedule, &source_positions);
230 #if ENABLE_DISASSEMBLER
231 if (!code.is_null() && FLAG_print_opt_code) {
232 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer());
233 OFStream os(tracing_scope.file());
234 code->Disassemble("test code", os);
235 }
236 #endif
237 return code;
238 }
239
240
241 Handle<Code> Pipeline::GenerateCode(Linkage* linkage, Graph* graph,
242 Schedule* schedule,
243 SourcePositionTable* source_positions) {
244 ASSERT_NOT_NULL(graph);
245 ASSERT_NOT_NULL(linkage);
246 ASSERT_NOT_NULL(schedule);
247 ASSERT(SupportedTarget());
248
249 InstructionSequence sequence(linkage, graph, schedule);
250
251 // Select and schedule instructions covering the scheduled graph.
252 {
253 InstructionSelector selector(&sequence, source_positions);
254 selector.SelectInstructions();
255 }
256
257 if (FLAG_trace_turbo) {
258 OFStream os(stdout);
259 os << "----- Instruction sequence before register allocation -----\n"
260 << sequence;
261 }
262
263 // Allocate registers.
264 {
265 int node_count = graph->NodeCount();
266 if (node_count > UnallocatedOperand::kMaxVirtualRegisters) {
267 linkage->info()->set_bailout_reason(kNotEnoughVirtualRegistersForValues);
268 return Handle<Code>::null();
269 }
270 RegisterAllocator allocator(&sequence);
271 if (!allocator.Allocate()) {
272 linkage->info()->set_bailout_reason(kNotEnoughVirtualRegistersRegalloc);
273 return Handle<Code>::null();
274 }
275 }
276
277 if (FLAG_trace_turbo) {
278 OFStream os(stdout);
279 os << "----- Instruction sequence after register allocation -----\n"
280 << sequence;
281 }
282
283 // Generate native sequence.
284 CodeGenerator generator(&sequence);
285 return generator.GenerateCode();
286 }
287
288 } // namespace compiler
289 } // namespace internal
290 } // namespace v8
OLDNEW
« 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