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

Side by Side Diff: src/compiler/ast-graph-builder.cc

Issue 1487973002: [turbofan] Add binary operation hints for javascript operators. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years 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
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/ast-graph-builder.h" 5 #include "src/compiler/ast-graph-builder.h"
6 6
7 #include "src/ast/scopes.h" 7 #include "src/ast/scopes.h"
8 #include "src/compiler.h" 8 #include "src/compiler.h"
9 #include "src/compiler/ast-loop-assignment-analyzer.h" 9 #include "src/compiler/ast-loop-assignment-analyzer.h"
10 #include "src/compiler/control-builders.h" 10 #include "src/compiler/control-builders.h"
11 #include "src/compiler/linkage.h" 11 #include "src/compiler/linkage.h"
12 #include "src/compiler/liveness-analyzer.h" 12 #include "src/compiler/liveness-analyzer.h"
13 #include "src/compiler/machine-operator.h" 13 #include "src/compiler/machine-operator.h"
14 #include "src/compiler/node-matchers.h" 14 #include "src/compiler/node-matchers.h"
15 #include "src/compiler/node-properties.h" 15 #include "src/compiler/node-properties.h"
16 #include "src/compiler/operator-properties.h" 16 #include "src/compiler/operator-properties.h"
17 #include "src/compiler/state-values-utils.h" 17 #include "src/compiler/state-values-utils.h"
18 #include "src/compiler/type-hint-analyzer.h"
18 #include "src/parsing/parser.h" 19 #include "src/parsing/parser.h"
19 20
20 namespace v8 { 21 namespace v8 {
21 namespace internal { 22 namespace internal {
22 namespace compiler { 23 namespace compiler {
23 24
24 25
25 // Each expression in the AST is evaluated in a specific context. This context 26 // Each expression in the AST is evaluated in a specific context. This context
26 // decides how the evaluation result is passed up the visitor. 27 // decides how the evaluation result is passed up the visitor.
27 class AstGraphBuilder::AstContext BASE_EMBEDDED { 28 class AstGraphBuilder::AstContext BASE_EMBEDDED {
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 } 422 }
422 } 423 }
423 424
424 private: 425 private:
425 AstGraphBuilder* builder_; 426 AstGraphBuilder* builder_;
426 Node* frame_state_before_; 427 Node* frame_state_before_;
427 }; 428 };
428 429
429 430
430 AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info, 431 AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info,
431 JSGraph* jsgraph, LoopAssignmentAnalysis* loop) 432 JSGraph* jsgraph, LoopAssignmentAnalysis* loop,
433 TypeHintAnalysis* type_hint_analysis)
432 : isolate_(info->isolate()), 434 : isolate_(info->isolate()),
433 local_zone_(local_zone), 435 local_zone_(local_zone),
434 info_(info), 436 info_(info),
435 jsgraph_(jsgraph), 437 jsgraph_(jsgraph),
436 environment_(nullptr), 438 environment_(nullptr),
437 ast_context_(nullptr), 439 ast_context_(nullptr),
438 globals_(0, local_zone), 440 globals_(0, local_zone),
439 execution_control_(nullptr), 441 execution_control_(nullptr),
440 execution_context_(nullptr), 442 execution_context_(nullptr),
441 try_catch_nesting_level_(0), 443 try_catch_nesting_level_(0),
442 try_nesting_level_(0), 444 try_nesting_level_(0),
443 input_buffer_size_(0), 445 input_buffer_size_(0),
444 input_buffer_(nullptr), 446 input_buffer_(nullptr),
445 exit_controls_(local_zone), 447 exit_controls_(local_zone),
446 loop_assignment_analysis_(loop), 448 loop_assignment_analysis_(loop),
449 type_hint_analysis_(type_hint_analysis),
447 state_values_cache_(jsgraph), 450 state_values_cache_(jsgraph),
448 liveness_analyzer_(static_cast<size_t>(info->scope()->num_stack_slots()), 451 liveness_analyzer_(static_cast<size_t>(info->scope()->num_stack_slots()),
449 local_zone), 452 local_zone),
450 frame_state_function_info_(common()->CreateFrameStateFunctionInfo( 453 frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
451 FrameStateType::kJavaScriptFunction, info->num_parameters() + 1, 454 FrameStateType::kJavaScriptFunction, info->num_parameters() + 1,
452 info->scope()->num_stack_slots(), info->shared_info(), 455 info->scope()->num_stack_slots(), info->shared_info(),
453 CALL_MAINTAINS_NATIVE_CONTEXT)) { 456 CALL_MAINTAINS_NATIVE_CONTEXT)) {
454 InitializeAstVisitor(info->isolate()); 457 InitializeAstVisitor(info->isolate());
455 } 458 }
456 459
(...skipping 1702 matching lines...) Expand 10 before | Expand all | Expand 10 after
2159 break; 2162 break;
2160 } 2163 }
2161 } 2164 }
2162 environment()->Push(old_value); 2165 environment()->Push(old_value);
2163 VisitForValue(expr->value()); 2166 VisitForValue(expr->value());
2164 Node* value; 2167 Node* value;
2165 { 2168 {
2166 FrameStateBeforeAndAfter states(this, expr->value()->id()); 2169 FrameStateBeforeAndAfter states(this, expr->value()->id());
2167 Node* right = environment()->Pop(); 2170 Node* right = environment()->Pop();
2168 Node* left = environment()->Pop(); 2171 Node* left = environment()->Pop();
2169 value = BuildBinaryOp(left, right, expr->binary_op()); 2172 value =
2173 BuildBinaryOp(left, right, expr->binary_op(),
2174 expr->binary_operation()->BinaryOperationFeedbackId());
2170 states.AddToNode(value, expr->binary_operation()->id(), 2175 states.AddToNode(value, expr->binary_operation()->id(),
2171 OutputFrameStateCombine::Push()); 2176 OutputFrameStateCombine::Push());
2172 } 2177 }
2173 environment()->Push(value); 2178 environment()->Push(value);
2174 if (needs_frame_state_before) { 2179 if (needs_frame_state_before) {
2175 before_store_id = expr->binary_operation()->id(); 2180 before_store_id = expr->binary_operation()->id();
2176 } 2181 }
2177 } else { 2182 } else {
2178 VisitForValue(expr->value()); 2183 VisitForValue(expr->value());
2179 if (needs_frame_state_before) { 2184 if (needs_frame_state_before) {
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after
2718 if (assign_type != VARIABLE) { 2723 if (assign_type != VARIABLE) {
2719 environment()->Poke(stack_depth, old_value); 2724 environment()->Poke(stack_depth, old_value);
2720 } else { 2725 } else {
2721 environment()->Push(old_value); 2726 environment()->Push(old_value);
2722 } 2727 }
2723 } 2728 }
2724 2729
2725 // Create node to perform +1/-1 operation. 2730 // Create node to perform +1/-1 operation.
2726 Node* value; 2731 Node* value;
2727 { 2732 {
2733 // TODO(bmeurer): Cleanup this feedback/bailout mess!
2728 FrameStateBeforeAndAfter states(this, BailoutId::None()); 2734 FrameStateBeforeAndAfter states(this, BailoutId::None());
2729 value = 2735 value = BuildBinaryOp(old_value, jsgraph()->OneConstant(),
2730 BuildBinaryOp(old_value, jsgraph()->OneConstant(), expr->binary_op()); 2736 expr->binary_op(), TypeFeedbackId::None());
2731 // This should never deoptimize outside strong mode because otherwise we 2737 // This should never deoptimize outside strong mode because otherwise we
2732 // have converted to number before. 2738 // have converted to number before.
2733 states.AddToNode(value, is_strong(language_mode()) ? expr->ToNumberId() 2739 states.AddToNode(value, is_strong(language_mode()) ? expr->ToNumberId()
2734 : BailoutId::None(), 2740 : BailoutId::None(),
2735 OutputFrameStateCombine::Ignore()); 2741 OutputFrameStateCombine::Ignore());
2736 } 2742 }
2737 2743
2738 // Store the value. 2744 // Store the value.
2739 VectorSlotPair feedback = CreateVectorSlotPair(expr->CountSlot()); 2745 VectorSlotPair feedback = CreateVectorSlotPair(expr->CountSlot());
2740 switch (assign_type) { 2746 switch (assign_type) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2803 return VisitComma(expr); 2809 return VisitComma(expr);
2804 case Token::OR: 2810 case Token::OR:
2805 case Token::AND: 2811 case Token::AND:
2806 return VisitLogicalExpression(expr); 2812 return VisitLogicalExpression(expr);
2807 default: { 2813 default: {
2808 VisitForValue(expr->left()); 2814 VisitForValue(expr->left());
2809 VisitForValue(expr->right()); 2815 VisitForValue(expr->right());
2810 FrameStateBeforeAndAfter states(this, expr->right()->id()); 2816 FrameStateBeforeAndAfter states(this, expr->right()->id());
2811 Node* right = environment()->Pop(); 2817 Node* right = environment()->Pop();
2812 Node* left = environment()->Pop(); 2818 Node* left = environment()->Pop();
2813 Node* value = BuildBinaryOp(left, right, expr->op()); 2819 Node* value = BuildBinaryOp(left, right, expr->op(),
2820 expr->BinaryOperationFeedbackId());
2814 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); 2821 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
2815 ast_context()->ProduceValue(value); 2822 ast_context()->ProduceValue(value);
2816 } 2823 }
2817 } 2824 }
2818 } 2825 }
2819 2826
2820 2827
2821 void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) { 2828 void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
2822 const Operator* op; 2829 const Operator* op;
2823 switch (expr->op()) { 2830 switch (expr->op()) {
(...skipping 950 matching lines...) Expand 10 before | Expand all | Expand 10 after
3774 3781
3775 3782
3776 Node* AstGraphBuilder::BuildThrow(Node* exception_value) { 3783 Node* AstGraphBuilder::BuildThrow(Node* exception_value) {
3777 NewNode(javascript()->CallRuntime(Runtime::kReThrow, 1), exception_value); 3784 NewNode(javascript()->CallRuntime(Runtime::kReThrow, 1), exception_value);
3778 Node* control = NewNode(common()->Throw(), exception_value); 3785 Node* control = NewNode(common()->Throw(), exception_value);
3779 UpdateControlDependencyToLeaveFunction(control); 3786 UpdateControlDependencyToLeaveFunction(control);
3780 return control; 3787 return control;
3781 } 3788 }
3782 3789
3783 3790
3784 Node* AstGraphBuilder::BuildBinaryOp(Node* left, Node* right, Token::Value op) { 3791 Node* AstGraphBuilder::BuildBinaryOp(Node* left, Node* right, Token::Value op,
3792 TypeFeedbackId feedback_id) {
3785 const Operator* js_op; 3793 const Operator* js_op;
3794 BinaryOperationHints hints;
3795 if (!type_hint_analysis_ ||
3796 !type_hint_analysis_->GetBinaryOperationHints(feedback_id, &hints)) {
3797 hints = BinaryOperationHints::Any();
3798 }
3786 switch (op) { 3799 switch (op) {
3787 case Token::BIT_OR: 3800 case Token::BIT_OR:
3788 js_op = javascript()->BitwiseOr(language_mode()); 3801 js_op = javascript()->BitwiseOr(language_mode(), hints);
3789 break; 3802 break;
3790 case Token::BIT_AND: 3803 case Token::BIT_AND:
3791 js_op = javascript()->BitwiseAnd(language_mode()); 3804 js_op = javascript()->BitwiseAnd(language_mode(), hints);
3792 break; 3805 break;
3793 case Token::BIT_XOR: 3806 case Token::BIT_XOR:
3794 js_op = javascript()->BitwiseXor(language_mode()); 3807 js_op = javascript()->BitwiseXor(language_mode(), hints);
3795 break; 3808 break;
3796 case Token::SHL: 3809 case Token::SHL:
3797 js_op = javascript()->ShiftLeft(language_mode()); 3810 js_op = javascript()->ShiftLeft(language_mode(), hints);
3798 break; 3811 break;
3799 case Token::SAR: 3812 case Token::SAR:
3800 js_op = javascript()->ShiftRight(language_mode()); 3813 js_op = javascript()->ShiftRight(language_mode(), hints);
3801 break; 3814 break;
3802 case Token::SHR: 3815 case Token::SHR:
3803 js_op = javascript()->ShiftRightLogical(language_mode()); 3816 js_op = javascript()->ShiftRightLogical(language_mode(), hints);
3804 break; 3817 break;
3805 case Token::ADD: 3818 case Token::ADD:
3806 js_op = javascript()->Add(language_mode()); 3819 js_op = javascript()->Add(language_mode(), hints);
3807 break; 3820 break;
3808 case Token::SUB: 3821 case Token::SUB:
3809 js_op = javascript()->Subtract(language_mode()); 3822 js_op = javascript()->Subtract(language_mode(), hints);
3810 break; 3823 break;
3811 case Token::MUL: 3824 case Token::MUL:
3812 js_op = javascript()->Multiply(language_mode()); 3825 js_op = javascript()->Multiply(language_mode(), hints);
3813 break; 3826 break;
3814 case Token::DIV: 3827 case Token::DIV:
3815 js_op = javascript()->Divide(language_mode()); 3828 js_op = javascript()->Divide(language_mode(), hints);
3816 break; 3829 break;
3817 case Token::MOD: 3830 case Token::MOD:
3818 js_op = javascript()->Modulus(language_mode()); 3831 js_op = javascript()->Modulus(language_mode(), hints);
3819 break; 3832 break;
3820 default: 3833 default:
3821 UNREACHABLE(); 3834 UNREACHABLE();
3822 js_op = NULL; 3835 js_op = NULL;
3823 } 3836 }
3824 return NewNode(js_op, left, right); 3837 return NewNode(js_op, left, right);
3825 } 3838 }
3826 3839
3827 3840
3828 Node* AstGraphBuilder::TryLoadGlobalConstant(Handle<Name> name) { 3841 Node* AstGraphBuilder::TryLoadGlobalConstant(Handle<Name> name) {
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after
4304 // Phi does not exist yet, introduce one. 4317 // Phi does not exist yet, introduce one.
4305 value = NewPhi(inputs, value, control); 4318 value = NewPhi(inputs, value, control);
4306 value->ReplaceInput(inputs - 1, other); 4319 value->ReplaceInput(inputs - 1, other);
4307 } 4320 }
4308 return value; 4321 return value;
4309 } 4322 }
4310 4323
4311 } // namespace compiler 4324 } // namespace compiler
4312 } // namespace internal 4325 } // namespace internal
4313 } // namespace v8 4326 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698