V8 Project
v8::internal::compiler::Pipeline Class Reference

#include <pipeline.h>

+ Collaboration diagram for v8::internal::compiler::Pipeline:

Public Member Functions

 Pipeline (CompilationInfo *info)
 
Handle< CodeGenerateCode ()
 
Handle< CodeGenerateCodeForMachineGraph (Linkage *linkage, Graph *graph, Schedule *schedule=NULL)
 

Static Public Member Functions

static bool SupportedBackend ()
 
static bool SupportedTarget ()
 
static void SetUp ()
 
static void TearDown ()
 

Private Member Functions

CompilationInfoinfo () const
 
Isolateisolate ()
 
Zonezone ()
 
ScheduleComputeSchedule (Graph *graph)
 
void VerifyAndPrintGraph (Graph *graph, const char *phase)
 
Handle< CodeGenerateCode (Linkage *linkage, Graph *graph, Schedule *schedule, SourcePositionTable *source_positions)
 

Private Attributes

CompilationInfoinfo_
 

Detailed Description

Definition at line 25 of file pipeline.h.

Constructor & Destructor Documentation

◆ Pipeline()

v8::internal::compiler::Pipeline::Pipeline ( CompilationInfo info)
inlineexplicit

Definition at line 27 of file pipeline.h.

27 : info_(info) {}
CompilationInfo * info() const
Definition: pipeline.h:46
CompilationInfo * info_
Definition: pipeline.h:44

Member Function Documentation

◆ ComputeSchedule()

Schedule * v8::internal::compiler::Pipeline::ComputeSchedule ( Graph graph)
private

Definition at line 347 of file pipeline.cc.

347  {
348  PhaseStats schedule_stats(info(), PhaseStats::CODEGEN, "scheduling");
349  Schedule* schedule = Scheduler::ComputeSchedule(graph);
350  TraceSchedule(schedule);
351  if (VerifyGraphs()) ScheduleVerifier::Run(schedule);
352  return schedule;
353 }
static void Run(Schedule *schedule)
Definition: verifier.cc:295
static Schedule * ComputeSchedule(Graph *graph)
Definition: scheduler.cc:237
static void TraceSchedule(Schedule *schedule)
Definition: pipeline.cc:159
static bool VerifyGraphs()
Definition: pipeline.cc:82

References v8::internal::compiler::PhaseStats::CODEGEN, v8::internal::compiler::Scheduler::ComputeSchedule(), info(), v8::internal::compiler::ScheduleVerifier::Run(), v8::internal::compiler::TraceSchedule(), and v8::internal::compiler::VerifyGraphs().

Referenced by GenerateCode(), and GenerateCodeForMachineGraph().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GenerateCode() [1/2]

Handle< Code > v8::internal::compiler::Pipeline::GenerateCode ( )

Definition at line 166 of file pipeline.cc.

166  {
167  if (info()->function()->dont_optimize_reason() == kTryCatchStatement ||
168  info()->function()->dont_optimize_reason() == kTryFinallyStatement ||
169  // TODO(turbofan): Make ES6 for-of work and remove this bailout.
170  info()->function()->dont_optimize_reason() == kForOfStatement ||
171  // TODO(turbofan): Make super work and remove this bailout.
172  info()->function()->dont_optimize_reason() == kSuperReference ||
173  // TODO(turbofan): Make OSR work and remove this bailout.
174  info()->is_osr()) {
175  return Handle<Code>::null();
176  }
177 
178  if (FLAG_turbo_stats) isolate()->GetTStatistics()->Initialize(info_);
179 
180  if (FLAG_trace_turbo) {
181  OFStream os(stdout);
182  os << "---------------------------------------------------\n"
183  << "Begin compiling method "
184  << info()->function()->debug_name()->ToCString().get()
185  << " using Turbofan" << endl;
186  }
187 
188  // Build the graph.
189  Graph graph(zone());
190  SourcePositionTable source_positions(&graph);
191  source_positions.AddDecorator();
192  // TODO(turbofan): there is no need to type anything during initial graph
193  // construction. This is currently only needed for the node cache, which the
194  // typer could sweep over later.
195  Typer typer(zone());
196  MachineOperatorBuilder machine;
197  CommonOperatorBuilder common(zone());
198  JSOperatorBuilder javascript(zone());
199  JSGraph jsgraph(&graph, &common, &javascript, &typer, &machine);
200  Node* context_node;
201  {
202  PhaseStats graph_builder_stats(info(), PhaseStats::CREATE_GRAPH,
203  "graph builder");
204  AstGraphBuilderWithPositions graph_builder(info(), &jsgraph,
205  &source_positions);
206  graph_builder.CreateGraph();
207  context_node = graph_builder.GetFunctionContext();
208  }
209  {
210  PhaseStats phi_reducer_stats(info(), PhaseStats::CREATE_GRAPH,
211  "phi reduction");
212  PhiReducer phi_reducer;
213  GraphReducer graph_reducer(&graph);
214  graph_reducer.AddReducer(&phi_reducer);
215  graph_reducer.ReduceGraph();
216  // TODO(mstarzinger): Running reducer once ought to be enough for everyone.
217  graph_reducer.ReduceGraph();
218  graph_reducer.ReduceGraph();
219  }
220 
221  VerifyAndPrintGraph(&graph, "Initial untyped");
222 
223  if (info()->is_context_specializing()) {
224  SourcePositionTable::Scope pos(&source_positions,
225  SourcePosition::Unknown());
226  // Specialize the code to the context as aggressively as possible.
227  JSContextSpecializer spec(info(), &jsgraph, context_node);
228  spec.SpecializeToContext();
229  VerifyAndPrintGraph(&graph, "Context specialized");
230  }
231 
232  if (info()->is_inlining_enabled()) {
233  SourcePositionTable::Scope pos(&source_positions,
234  SourcePosition::Unknown());
235  JSInliner inliner(info(), &jsgraph);
236  inliner.Inline();
237  VerifyAndPrintGraph(&graph, "Inlined");
238  }
239 
240  // Print a replay of the initial graph.
241  if (FLAG_print_turbo_replay) {
242  GraphReplayPrinter::PrintReplay(&graph);
243  }
244 
245  // Bailout here in case target architecture is not supported.
246  if (!SupportedTarget()) return Handle<Code>::null();
247 
248  if (info()->is_typing_enabled()) {
249  {
250  // Type the graph.
251  PhaseStats typer_stats(info(), PhaseStats::CREATE_GRAPH, "typer");
252  typer.Run(&graph, info()->context());
253  VerifyAndPrintGraph(&graph, "Typed");
254  }
255  // All new nodes must be typed.
256  typer.DecorateGraph(&graph);
257  {
258  // Lower JSOperators where we can determine types.
259  PhaseStats lowering_stats(info(), PhaseStats::CREATE_GRAPH,
260  "typed lowering");
261  SourcePositionTable::Scope pos(&source_positions,
262  SourcePosition::Unknown());
263  JSTypedLowering lowering(&jsgraph);
264  GraphReducer graph_reducer(&graph);
265  graph_reducer.AddReducer(&lowering);
266  graph_reducer.ReduceGraph();
267 
268  VerifyAndPrintGraph(&graph, "Lowered typed");
269  }
270  {
271  // Lower simplified operators and insert changes.
272  PhaseStats lowering_stats(info(), PhaseStats::CREATE_GRAPH,
273  "simplified lowering");
274  SourcePositionTable::Scope pos(&source_positions,
275  SourcePosition::Unknown());
276  SimplifiedLowering lowering(&jsgraph);
277  lowering.LowerAllNodes();
278 
279  VerifyAndPrintGraph(&graph, "Lowered simplified");
280  }
281  {
282  // Lower changes that have been inserted before.
283  PhaseStats lowering_stats(info(), PhaseStats::OPTIMIZATION,
284  "change lowering");
285  SourcePositionTable::Scope pos(&source_positions,
286  SourcePosition::Unknown());
287  Linkage linkage(info());
288  // TODO(turbofan): Value numbering disabled for now.
289  // ValueNumberingReducer vn_reducer(zone());
290  SimplifiedOperatorReducer simple_reducer(&jsgraph);
291  ChangeLowering lowering(&jsgraph, &linkage);
292  MachineOperatorReducer mach_reducer(&jsgraph);
293  GraphReducer graph_reducer(&graph);
294  // TODO(titzer): Figure out if we should run all reducers at once here.
295  // graph_reducer.AddReducer(&vn_reducer);
296  graph_reducer.AddReducer(&simple_reducer);
297  graph_reducer.AddReducer(&lowering);
298  graph_reducer.AddReducer(&mach_reducer);
299  graph_reducer.ReduceGraph();
300 
301  VerifyAndPrintGraph(&graph, "Lowered changes");
302  }
303  }
304 
305  {
306  // Lower any remaining generic JSOperators.
307  PhaseStats lowering_stats(info(), PhaseStats::CREATE_GRAPH,
308  "generic lowering");
309  SourcePositionTable::Scope pos(&source_positions,
310  SourcePosition::Unknown());
311  JSGenericLowering lowering(info(), &jsgraph);
312  GraphReducer graph_reducer(&graph);
313  graph_reducer.AddReducer(&lowering);
314  graph_reducer.ReduceGraph();
315 
316  VerifyAndPrintGraph(&graph, "Lowered generic");
317  }
318 
319  source_positions.RemoveDecorator();
320 
321  Handle<Code> code = Handle<Code>::null();
322  {
323  // Compute a schedule.
324  Schedule* schedule = ComputeSchedule(&graph);
325  // Generate optimized code.
326  PhaseStats codegen_stats(info(), PhaseStats::CODEGEN, "codegen");
327  Linkage linkage(info());
328  code = GenerateCode(&linkage, &graph, schedule, &source_positions);
329  info()->SetCode(code);
330  }
331 
332  // Print optimized code.
334 
335  if (FLAG_trace_turbo) {
336  OFStream os(stdout);
337  os << "--------------------------------------------------\n"
338  << "Finished compiling method "
339  << info()->function()->debug_name()->ToCString().get()
340  << " using Turbofan" << endl;
341  }
342 
343  return code;
344 }
static void PrintCode(Handle< Code > code, CompilationInfo *info)
Definition: codegen.cc:163
void SetCode(Handle< Code > code)
Definition: compiler.h:242
FunctionLiteral * function() const
Definition: compiler.h:107
static Handle< T > null()
Definition: handles.h:123
HStatistics * GetTStatistics()
Definition: isolate.cc:2142
Handle< Code > GenerateCode()
Definition: pipeline.cc:166
Schedule * ComputeSchedule(Graph *graph)
Definition: pipeline.cc:347
void VerifyAndPrintGraph(Graph *graph, const char *phase)
Definition: pipeline.cc:91
OStream & endl(OStream &os)
Definition: ostreams.cc:112

References v8::internal::compiler::PhaseStats::CODEGEN, ComputeSchedule(), v8::internal::compiler::PhaseStats::CREATE_GRAPH, v8::internal::compiler::AstGraphBuilderWithPositions::CreateGraph(), v8::internal::compiler::Typer::DecorateGraph(), v8::internal::endl(), v8::internal::CompilationInfo::function(), v8::internal::compiler::AstGraphBuilder::GetFunctionContext(), v8::internal::Isolate::GetTStatistics(), info(), info_, v8::internal::compiler::JSInliner::Inline(), isolate(), v8::internal::compiler::SimplifiedLowering::LowerAllNodes(), v8::internal::Handle< T >::null(), v8::internal::compiler::PhaseStats::OPTIMIZATION, v8::internal::CodeGenerator::PrintCode(), v8::internal::compiler::Typer::Run(), v8::internal::CompilationInfo::SetCode(), v8::internal::compiler::JSContextSpecializer::SpecializeToContext(), SupportedTarget(), VerifyAndPrintGraph(), and zone().

Referenced by v8::internal::OptimizedCompileJob::CreateGraph(), and GenerateCodeForMachineGraph().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GenerateCode() [2/2]

Handle< Code > v8::internal::compiler::Pipeline::GenerateCode ( Linkage linkage,
Graph graph,
Schedule schedule,
SourcePositionTable *  source_positions 
)
private

Definition at line 379 of file pipeline.cc.

381  {
382  DCHECK_NOT_NULL(graph);
383  DCHECK_NOT_NULL(linkage);
384  DCHECK_NOT_NULL(schedule);
386 
387  BasicBlockProfiler::Data* profiler_data = NULL;
388  if (FLAG_turbo_profiling) {
389  profiler_data = BasicBlockInstrumentor::Instrument(info_, graph, schedule);
390  }
391 
392  InstructionSequence sequence(linkage, graph, schedule);
393 
394  // Select and schedule instructions covering the scheduled graph.
395  {
396  InstructionSelector selector(&sequence, source_positions);
397  selector.SelectInstructions();
398  }
399 
400  if (FLAG_trace_turbo) {
401  OFStream os(stdout);
402  os << "----- Instruction sequence before register allocation -----\n"
403  << sequence;
404  }
405 
406  // Allocate registers.
407  {
408  int node_count = graph->NodeCount();
409  if (node_count > UnallocatedOperand::kMaxVirtualRegisters) {
410  linkage->info()->AbortOptimization(kNotEnoughVirtualRegistersForValues);
411  return Handle<Code>::null();
412  }
413  RegisterAllocator allocator(&sequence);
414  if (!allocator.Allocate()) {
415  linkage->info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc);
416  return Handle<Code>::null();
417  }
418  }
419 
420  if (FLAG_trace_turbo) {
421  OFStream os(stdout);
422  os << "----- Instruction sequence after register allocation -----\n"
423  << sequence;
424  }
425 
426  // Generate native sequence.
427  CodeGenerator generator(&sequence);
428  Handle<Code> code = generator.GenerateCode();
429  if (profiler_data != NULL) {
430 #if ENABLE_DISASSEMBLER
431  OStringStream os;
432  code->Disassemble(NULL, os);
433  profiler_data->SetCode(&os);
434 #endif
435  }
436  return code;
437 }
static BasicBlockProfiler::Data * Instrument(CompilationInfo *info, Graph *graph, Schedule *schedule)
static bool SupportedBackend()
Definition: pipeline.h:37
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define CHECK(condition)
Definition: logging.h:36
#define DCHECK_NOT_NULL(p)
Definition: logging.h:213

References v8::internal::CompilationInfo::AbortOptimization(), CHECK, DCHECK_NOT_NULL, v8::internal::compiler::Linkage::info(), info_, v8::internal::compiler::BasicBlockInstrumentor::Instrument(), v8::internal::compiler::UnallocatedOperand::kMaxVirtualRegisters, v8::internal::compiler::GenericGraphBase::NodeCount(), NULL, v8::internal::Handle< T >::null(), v8::internal::BasicBlockProfiler::Data::SetCode(), and SupportedBackend().

+ Here is the call graph for this function:

◆ GenerateCodeForMachineGraph()

Handle< Code > v8::internal::compiler::Pipeline::GenerateCodeForMachineGraph ( Linkage linkage,
Graph graph,
Schedule schedule = NULL 
)

Definition at line 356 of file pipeline.cc.

358  {
360  if (schedule == NULL) {
361  VerifyAndPrintGraph(graph, "Machine");
362  schedule = ComputeSchedule(graph);
363  }
364  TraceSchedule(schedule);
365 
366  SourcePositionTable source_positions(graph);
367  Handle<Code> code = GenerateCode(linkage, graph, schedule, &source_positions);
368 #if ENABLE_DISASSEMBLER
369  if (!code.is_null() && FLAG_print_opt_code) {
370  CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer());
371  OFStream os(tracing_scope.file());
372  code->Disassemble("test code", os);
373  }
374 #endif
375  return code;
376 }

References CHECK, ComputeSchedule(), GenerateCode(), v8::internal::Handle< T >::is_null(), isolate(), NULL, SupportedBackend(), v8::internal::compiler::TraceSchedule(), and VerifyAndPrintGraph().

+ Here is the call graph for this function:

◆ info()

CompilationInfo* v8::internal::compiler::Pipeline::info ( ) const
inlineprivate

Definition at line 46 of file pipeline.h.

46 { return info_; }

References info_.

Referenced by ComputeSchedule(), and GenerateCode().

+ Here is the caller graph for this function:

◆ isolate()

Isolate* v8::internal::compiler::Pipeline::isolate ( )
inlineprivate

Definition at line 47 of file pipeline.h.

47 { return info_->isolate(); }
Isolate * isolate() const
Definition: compiler.h:96

References info_, and v8::internal::CompilationInfo::isolate().

Referenced by GenerateCode(), and GenerateCodeForMachineGraph().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ SetUp()

void v8::internal::compiler::Pipeline::SetUp ( )
static

Definition at line 440 of file pipeline.cc.

References v8::internal::compiler::InstructionOperand::SetUpCaches().

Referenced by v8::internal::V8::InitializeOncePerProcessImpl().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ SupportedBackend()

static bool v8::internal::compiler::Pipeline::SupportedBackend ( )
inlinestatic

Definition at line 37 of file pipeline.h.

37 { return V8_TURBOFAN_BACKEND != 0; }
#define V8_TURBOFAN_BACKEND
Definition: globals.h:32

References V8_TURBOFAN_BACKEND.

Referenced by GenerateCode(), and GenerateCodeForMachineGraph().

+ Here is the caller graph for this function:

◆ SupportedTarget()

static bool v8::internal::compiler::Pipeline::SupportedTarget ( )
inlinestatic

Definition at line 38 of file pipeline.h.

38 { return V8_TURBOFAN_TARGET != 0; }
#define V8_TURBOFAN_TARGET
Definition: globals.h:37

References V8_TURBOFAN_TARGET.

Referenced by GenerateCode().

+ Here is the caller graph for this function:

◆ TearDown()

void v8::internal::compiler::Pipeline::TearDown ( )
static

Definition at line 445 of file pipeline.cc.

References v8::internal::compiler::InstructionOperand::TearDownCaches().

Referenced by v8::internal::V8::TearDown().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ VerifyAndPrintGraph()

void v8::internal::compiler::Pipeline::VerifyAndPrintGraph ( Graph graph,
const char *  phase 
)
private

Definition at line 91 of file pipeline.cc.

91  {
92  if (FLAG_trace_turbo) {
93  char buffer[256];
94  Vector<char> filename(buffer, sizeof(buffer));
95  if (!info_->shared_info().is_null()) {
96  SmartArrayPointer<char> functionname =
97  info_->shared_info()->DebugName()->ToCString();
98  if (strlen(functionname.get()) > 0) {
99  SNPrintF(filename, "turbo-%s-%s", functionname.get(), phase);
100  } else {
101  SNPrintF(filename, "turbo-%p-%s", static_cast<void*>(info_), phase);
102  }
103  } else {
104  SNPrintF(filename, "turbo-none-%s", phase);
105  }
106  std::replace(filename.start(), filename.start() + filename.length(), ' ',
107  '_');
108 
109  char dot_buffer[256];
110  Vector<char> dot_filename(dot_buffer, sizeof(dot_buffer));
111  SNPrintF(dot_filename, "%s.dot", filename.start());
112  FILE* dot_file = base::OS::FOpen(dot_filename.start(), "w+");
113  OFStream dot_of(dot_file);
114  dot_of << AsDOT(*graph);
115  fclose(dot_file);
116 
117  char json_buffer[256];
118  Vector<char> json_filename(json_buffer, sizeof(json_buffer));
119  SNPrintF(json_filename, "%s.json", filename.start());
120  FILE* json_file = base::OS::FOpen(json_filename.start(), "w+");
121  OFStream json_of(json_file);
122  json_of << AsJSON(*graph);
123  fclose(json_file);
124 
125  OFStream os(stdout);
126  os << "-- " << phase << " graph printed to file " << filename.start()
127  << "\n";
128  }
129  if (VerifyGraphs()) Verifier::Run(graph);
130 }
static FILE * FOpen(const char *path, const char *mode)
Handle< SharedFunctionInfo > shared_info() const
Definition: compiler.h:112
static void Run(Graph *graph)
Definition: verifier.cc:237
int SNPrintF(Vector< char > str, const char *format,...)
Definition: utils.cc:105

References v8::base::OS::FOpen(), v8::internal::SmartPointerBase< Deallocator, T >::get(), info_, v8::internal::Vector< T >::length(), v8::internal::compiler::Verifier::Run(), v8::internal::CompilationInfo::shared_info(), v8::internal::SNPrintF(), v8::internal::Vector< T >::start(), and v8::internal::compiler::VerifyGraphs().

Referenced by GenerateCode(), and GenerateCodeForMachineGraph().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ zone()

Zone* v8::internal::compiler::Pipeline::zone ( )
inlineprivate

Definition at line 48 of file pipeline.h.

48 { return info_->zone(); }

References info_, and v8::internal::CompilationInfo::zone().

Referenced by GenerateCode().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Member Data Documentation

◆ info_

CompilationInfo* v8::internal::compiler::Pipeline::info_
private

Definition at line 44 of file pipeline.h.

Referenced by GenerateCode(), info(), isolate(), VerifyAndPrintGraph(), and zone().


The documentation for this class was generated from the following files: