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

Side by Side Diff: src/compiler/js-inlining.cc

Issue 2262033003: [turbofan] Allow inlining into BytecodeGraphBuilder graph. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@local_interpreter-preserve-bytecode-5
Patch Set: Rebased. Created 4 years, 3 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
« no previous file with comments | « no previous file | src/compiler/pipeline.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/js-inlining.h" 5 #include "src/compiler/js-inlining.h"
6 6
7 #include "src/ast/ast-numbering.h" 7 #include "src/ast/ast-numbering.h"
8 #include "src/ast/ast.h" 8 #include "src/ast/ast.h"
9 #include "src/ast/scopes.h" 9 #include "src/ast/scopes.h"
10 #include "src/compiler.h" 10 #include "src/compiler.h"
11 #include "src/compiler/ast-graph-builder.h" 11 #include "src/compiler/ast-graph-builder.h"
12 #include "src/compiler/ast-loop-assignment-analyzer.h" 12 #include "src/compiler/ast-loop-assignment-analyzer.h"
13 #include "src/compiler/bytecode-graph-builder.h"
13 #include "src/compiler/common-operator.h" 14 #include "src/compiler/common-operator.h"
14 #include "src/compiler/graph-reducer.h" 15 #include "src/compiler/graph-reducer.h"
15 #include "src/compiler/js-operator.h" 16 #include "src/compiler/js-operator.h"
16 #include "src/compiler/node-matchers.h" 17 #include "src/compiler/node-matchers.h"
17 #include "src/compiler/node-properties.h" 18 #include "src/compiler/node-properties.h"
18 #include "src/compiler/operator-properties.h" 19 #include "src/compiler/operator-properties.h"
19 #include "src/compiler/simplified-operator.h" 20 #include "src/compiler/simplified-operator.h"
20 #include "src/compiler/type-hint-analyzer.h" 21 #include "src/compiler/type-hint-analyzer.h"
21 #include "src/isolate-inl.h" 22 #include "src/isolate-inl.h"
22 #include "src/parsing/parse-info.h" 23 #include "src/parsing/parse-info.h"
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 shared_info->DebugName()->ToCString().get(), 351 shared_info->DebugName()->ToCString().get(),
351 info_->shared_info()->DebugName()->ToCString().get()); 352 info_->shared_info()->DebugName()->ToCString().get());
352 return NoChange(); 353 return NoChange();
353 } 354 }
354 355
355 Zone zone(info_->isolate()->allocator()); 356 Zone zone(info_->isolate()->allocator());
356 ParseInfo parse_info(&zone, function); 357 ParseInfo parse_info(&zone, function);
357 CompilationInfo info(&parse_info, function); 358 CompilationInfo info(&parse_info, function);
358 if (info_->is_deoptimization_enabled()) info.MarkAsDeoptimizationEnabled(); 359 if (info_->is_deoptimization_enabled()) info.MarkAsDeoptimizationEnabled();
359 if (info_->is_type_feedback_enabled()) info.MarkAsTypeFeedbackEnabled(); 360 if (info_->is_type_feedback_enabled()) info.MarkAsTypeFeedbackEnabled();
361 if (info_->is_optimizing_from_bytecode()) info.MarkAsOptimizeFromBytecode();
360 362
361 if (!Compiler::ParseAndAnalyze(info.parse_info())) { 363 if (info.is_optimizing_from_bytecode() && !Compiler::EnsureBytecode(&info)) {
364 TRACE("Not inlining %s into %s because bytecode generation failed\n",
365 shared_info->DebugName()->ToCString().get(),
366 info_->shared_info()->DebugName()->ToCString().get());
367 DCHECK(!info_->isolate()->has_pending_exception());
368 return NoChange();
369 }
370
371 if (!info.is_optimizing_from_bytecode() &&
372 !Compiler::ParseAndAnalyze(info.parse_info())) {
362 TRACE("Not inlining %s into %s because parsing failed\n", 373 TRACE("Not inlining %s into %s because parsing failed\n",
363 shared_info->DebugName()->ToCString().get(), 374 shared_info->DebugName()->ToCString().get(),
364 info_->shared_info()->DebugName()->ToCString().get()); 375 info_->shared_info()->DebugName()->ToCString().get());
365 if (info_->isolate()->has_pending_exception()) { 376 if (info_->isolate()->has_pending_exception()) {
366 info_->isolate()->clear_pending_exception(); 377 info_->isolate()->clear_pending_exception();
367 } 378 }
368 return NoChange(); 379 return NoChange();
369 } 380 }
370 381
371 if (!Compiler::EnsureDeoptimizationSupport(&info)) { 382 if (!info.is_optimizing_from_bytecode() &&
383 !Compiler::EnsureDeoptimizationSupport(&info)) {
372 TRACE("Not inlining %s into %s because deoptimization support failed\n", 384 TRACE("Not inlining %s into %s because deoptimization support failed\n",
373 shared_info->DebugName()->ToCString().get(), 385 shared_info->DebugName()->ToCString().get(),
374 info_->shared_info()->DebugName()->ToCString().get()); 386 info_->shared_info()->DebugName()->ToCString().get());
375 return NoChange(); 387 return NoChange();
376 } 388 }
377 389
378 // Remember that we inlined this function. This needs to be called right 390 // Remember that we inlined this function. This needs to be called right
379 // after we ensure deoptimization support so that the code flusher 391 // after we ensure deoptimization support so that the code flusher
380 // does not remove the code with the deoptimization support. 392 // does not remove the code with the deoptimization support.
381 info_->AddInlinedFunction(shared_info); 393 info_->AddInlinedFunction(shared_info);
382 394
383 // ---------------------------------------------------------------- 395 // ----------------------------------------------------------------
384 // After this point, we've made a decision to inline this function. 396 // After this point, we've made a decision to inline this function.
385 // We shall not bailout from inlining if we got here. 397 // We shall not bailout from inlining if we got here.
386 398
387 TRACE("Inlining %s into %s\n", 399 TRACE("Inlining %s into %s\n",
388 shared_info->DebugName()->ToCString().get(), 400 shared_info->DebugName()->ToCString().get(),
389 info_->shared_info()->DebugName()->ToCString().get()); 401 info_->shared_info()->DebugName()->ToCString().get());
390 402
391 // If function was lazily compiled, it's literals array may not yet be set up. 403 // If function was lazily compiled, it's literals array may not yet be set up.
392 JSFunction::EnsureLiterals(function); 404 JSFunction::EnsureLiterals(function);
393 405
394 // Create the subgraph for the inlinee. 406 // Create the subgraph for the inlinee.
395 Node* start; 407 Node* start;
396 Node* end; 408 Node* end;
397 { 409 if (info.is_optimizing_from_bytecode()) {
410 // Run the BytecodeGraphBuilder to create the subgraph.
411 Graph::SubgraphScope scope(graph());
412 BytecodeGraphBuilder graph_builder(&zone, &info, jsgraph());
413 graph_builder.CreateGraph();
414
rmcilroy 2016/08/25 08:53:26 Do we want todos about the loop analysis and Tyler
Michael Starzinger 2016/08/25 09:01:26 The LoopAssignmentAnalyzer is an AST-based analysi
rmcilroy 2016/08/25 09:33:06 Makes sense, thanks for the explanation.
rmcilroy 2016/08/25 09:33:06 Makes sense, thanks for the explanation.
415 // Extract the inlinee start/end nodes.
416 start = graph()->start();
417 end = graph()->end();
418 } else {
398 // Run the loop assignment analyzer on the inlinee. 419 // Run the loop assignment analyzer on the inlinee.
399 AstLoopAssignmentAnalyzer loop_assignment_analyzer(&zone, &info); 420 AstLoopAssignmentAnalyzer loop_assignment_analyzer(&zone, &info);
400 LoopAssignmentAnalysis* loop_assignment = 421 LoopAssignmentAnalysis* loop_assignment =
401 loop_assignment_analyzer.Analyze(); 422 loop_assignment_analyzer.Analyze();
402 423
403 // Run the type hint analyzer on the inlinee. 424 // Run the type hint analyzer on the inlinee.
404 TypeHintAnalyzer type_hint_analyzer(&zone); 425 TypeHintAnalyzer type_hint_analyzer(&zone);
405 TypeHintAnalysis* type_hint_analysis = 426 TypeHintAnalysis* type_hint_analysis =
406 type_hint_analyzer.Analyze(handle(shared_info->code(), info.isolate())); 427 type_hint_analyzer.Analyze(handle(shared_info->code(), info.isolate()));
407 428
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 // type feedback in the compiler. 489 // type feedback in the compiler.
469 Node* context = jsgraph()->Constant(handle(function->context())); 490 Node* context = jsgraph()->Constant(handle(function->context()));
470 491
471 // Insert a JSConvertReceiver node for sloppy callees. Note that the context 492 // Insert a JSConvertReceiver node for sloppy callees. Note that the context
472 // passed into this node has to be the callees context (loaded above). Note 493 // passed into this node has to be the callees context (loaded above). Note
473 // that the frame state passed to the JSConvertReceiver must be the frame 494 // that the frame state passed to the JSConvertReceiver must be the frame
474 // state _before_ the call; it is not necessary to fiddle with the receiver 495 // state _before_ the call; it is not necessary to fiddle with the receiver
475 // in that frame state tho, as the conversion of the receiver can be repeated 496 // in that frame state tho, as the conversion of the receiver can be repeated
476 // any number of times, it's not observable. 497 // any number of times, it's not observable.
477 if (node->opcode() == IrOpcode::kJSCallFunction && 498 if (node->opcode() == IrOpcode::kJSCallFunction &&
478 is_sloppy(parse_info.language_mode()) && !shared_info->native()) { 499 is_sloppy(shared_info->language_mode()) && !shared_info->native()) {
479 const CallFunctionParameters& p = CallFunctionParametersOf(node->op()); 500 const CallFunctionParameters& p = CallFunctionParametersOf(node->op());
480 Node* frame_state_before = NodeProperties::FindFrameStateBefore(node); 501 Node* frame_state_before = NodeProperties::FindFrameStateBefore(node);
481 Node* effect = NodeProperties::GetEffectInput(node); 502 Node* effect = NodeProperties::GetEffectInput(node);
482 Node* convert = graph()->NewNode( 503 Node* convert = graph()->NewNode(
483 javascript()->ConvertReceiver(p.convert_mode()), call.receiver(), 504 javascript()->ConvertReceiver(p.convert_mode()), call.receiver(),
484 context, frame_state_before, effect, start); 505 context, frame_state_before, effect, start);
485 NodeProperties::ReplaceValueInput(node, convert, 1); 506 NodeProperties::ReplaceValueInput(node, convert, 1);
486 NodeProperties::ReplaceEffectInput(node, convert); 507 NodeProperties::ReplaceEffectInput(node, convert);
487 } 508 }
488 509
489 // If we are inlining a JS call at tail position then we have to pop current 510 // If we are inlining a JS call at tail position then we have to pop current
490 // frame state and its potential arguments adaptor frame state in order to 511 // frame state and its potential arguments adaptor frame state in order to
491 // make the call stack be consistent with non-inlining case. 512 // make the call stack be consistent with non-inlining case.
492 // After that we add a tail caller frame state which lets deoptimizer handle 513 // After that we add a tail caller frame state which lets deoptimizer handle
493 // the case when the outermost function inlines a tail call (it should remove 514 // the case when the outermost function inlines a tail call (it should remove
494 // potential arguments adaptor frame that belongs to outermost function when 515 // potential arguments adaptor frame that belongs to outermost function when
495 // deopt happens). 516 // deopt happens).
496 if (node->opcode() == IrOpcode::kJSCallFunction) { 517 if (node->opcode() == IrOpcode::kJSCallFunction) {
497 const CallFunctionParameters& p = CallFunctionParametersOf(node->op()); 518 const CallFunctionParameters& p = CallFunctionParametersOf(node->op());
498 if (p.tail_call_mode() == TailCallMode::kAllow) { 519 if (p.tail_call_mode() == TailCallMode::kAllow) {
499 frame_state = CreateTailCallerFrameState(node, frame_state); 520 frame_state = CreateTailCallerFrameState(node, frame_state);
500 } 521 }
501 } 522 }
502 523
503 // Insert argument adaptor frame if required. The callees formal parameter 524 // Insert argument adaptor frame if required. The callees formal parameter
504 // count (i.e. value outputs of start node minus target, receiver, new target, 525 // count (i.e. value outputs of start node minus target, receiver, new target,
505 // arguments count and context) have to match the number of arguments passed 526 // arguments count and context) have to match the number of arguments passed
506 // to the call. 527 // to the call.
507 int parameter_count = info.literal()->parameter_count(); 528 int parameter_count = shared_info->internal_formal_parameter_count();
508 DCHECK_EQ(parameter_count, start->op()->ValueOutputCount() - 5); 529 DCHECK_EQ(parameter_count, start->op()->ValueOutputCount() - 5);
509 if (call.formal_arguments() != parameter_count) { 530 if (call.formal_arguments() != parameter_count) {
510 frame_state = CreateArtificialFrameState( 531 frame_state = CreateArtificialFrameState(
511 node, frame_state, call.formal_arguments(), 532 node, frame_state, call.formal_arguments(),
512 FrameStateType::kArgumentsAdaptor, shared_info); 533 FrameStateType::kArgumentsAdaptor, shared_info);
513 } 534 }
514 535
515 return InlineCall(node, new_target, context, frame_state, start, end); 536 return InlineCall(node, new_target, context, frame_state, start, end);
516 } 537 }
517 538
518 Graph* JSInliner::graph() const { return jsgraph()->graph(); } 539 Graph* JSInliner::graph() const { return jsgraph()->graph(); }
519 540
520 JSOperatorBuilder* JSInliner::javascript() const { 541 JSOperatorBuilder* JSInliner::javascript() const {
521 return jsgraph()->javascript(); 542 return jsgraph()->javascript();
522 } 543 }
523 544
524 CommonOperatorBuilder* JSInliner::common() const { return jsgraph()->common(); } 545 CommonOperatorBuilder* JSInliner::common() const { return jsgraph()->common(); }
525 546
526 SimplifiedOperatorBuilder* JSInliner::simplified() const { 547 SimplifiedOperatorBuilder* JSInliner::simplified() const {
527 return jsgraph()->simplified(); 548 return jsgraph()->simplified();
528 } 549 }
529 550
530 } // namespace compiler 551 } // namespace compiler
531 } // namespace internal 552 } // namespace internal
532 } // namespace v8 553 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/compiler/pipeline.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698