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

Side by Side Diff: runtime/vm/flow_graph_builder.cc

Issue 78733002: Generalize if-conversion to arbitrary smi comparisons. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/compiler.cc ('k') | runtime/vm/flow_graph_compiler.h » ('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 (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/flow_graph_builder.h" 5 #include "vm/flow_graph_builder.h"
6 6
7 #include "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "vm/ast_printer.h" 8 #include "vm/ast_printer.h"
9 #include "vm/bit_vector.h" 9 #include "vm/bit_vector.h"
10 #include "vm/class_finalizer.h" 10 #include "vm/class_finalizer.h"
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 call_block->try_index()); 426 call_block->try_index());
427 false_block->InheritDeoptTargetAfter(call_); 427 false_block->InheritDeoptTargetAfter(call_);
428 false_block->LinkTo(call_->next()); 428 false_block->LinkTo(call_->next());
429 call_block->ReplaceAsPredecessorWith(false_block); 429 call_block->ReplaceAsPredecessorWith(false_block);
430 430
431 ConstantInstr* true_const = caller_graph_->GetConstant(Bool::True()); 431 ConstantInstr* true_const = caller_graph_->GetConstant(Bool::True());
432 BranchInstr* branch = 432 BranchInstr* branch =
433 new BranchInstr(new StrictCompareInstr(call_block->start_pos(), 433 new BranchInstr(new StrictCompareInstr(call_block->start_pos(),
434 Token::kEQ_STRICT, 434 Token::kEQ_STRICT,
435 new Value(true_const), 435 new Value(true_const),
436 new Value(true_const))); 436 new Value(true_const),
437 false)); // No number check.
437 branch->InheritDeoptTarget(call_); 438 branch->InheritDeoptTarget(call_);
438 *branch->true_successor_address() = callee_entry; 439 *branch->true_successor_address() = callee_entry;
439 *branch->false_successor_address() = false_block; 440 *branch->false_successor_address() = false_block;
440 441
441 call_->previous()->AppendInstruction(branch); 442 call_->previous()->AppendInstruction(branch);
442 call_block->set_last_instruction(branch); 443 call_block->set_last_instruction(branch);
443 444
444 // Update dominator tree. 445 // Update dominator tree.
445 call_block->AddDominatedBlock(callee_entry); 446 call_block->AddDominatedBlock(callee_entry);
446 call_block->AddDominatedBlock(false_block); 447 call_block->AddDominatedBlock(false_block);
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
826 827
827 void TestGraphVisitor::ReturnValue(Value* value) { 828 void TestGraphVisitor::ReturnValue(Value* value) {
828 if (FLAG_enable_type_checks) { 829 if (FLAG_enable_type_checks) {
829 value = Bind(new AssertBooleanInstr(condition_token_pos(), value)); 830 value = Bind(new AssertBooleanInstr(condition_token_pos(), value));
830 } 831 }
831 Value* constant_true = Bind(new ConstantInstr(Bool::True())); 832 Value* constant_true = Bind(new ConstantInstr(Bool::True()));
832 StrictCompareInstr* comp = 833 StrictCompareInstr* comp =
833 new StrictCompareInstr(condition_token_pos(), 834 new StrictCompareInstr(condition_token_pos(),
834 Token::kEQ_STRICT, 835 Token::kEQ_STRICT,
835 value, 836 value,
836 constant_true); 837 constant_true,
837 comp->set_needs_number_check(false); 838 false); // No number check.
838 BranchInstr* branch = new BranchInstr(comp); 839 BranchInstr* branch = new BranchInstr(comp);
839 AddInstruction(branch); 840 AddInstruction(branch);
840 CloseFragment(); 841 CloseFragment();
841 842
842 true_successor_addresses_.Add(branch->true_successor_address()); 843 true_successor_addresses_.Add(branch->true_successor_address());
843 false_successor_addresses_.Add(branch->false_successor_address()); 844 false_successor_addresses_.Add(branch->false_successor_address());
844 } 845 }
845 846
846 847
847 void TestGraphVisitor::MergeBranchWithComparison(ComparisonInstr* comp) { 848 void TestGraphVisitor::MergeBranchWithComparison(ComparisonInstr* comp) {
848 BranchInstr* branch; 849 BranchInstr* branch;
849 if (Token::IsStrictEqualityOperator(comp->kind())) { 850 if (Token::IsStrictEqualityOperator(comp->kind())) {
850 ASSERT(comp->IsStrictCompare()); 851 ASSERT(comp->IsStrictCompare());
851 branch = new BranchInstr(comp); 852 branch = new BranchInstr(comp);
852 } else if (Token::IsEqualityOperator(comp->kind()) && 853 } else if (Token::IsEqualityOperator(comp->kind()) &&
853 (comp->left()->BindsToConstantNull() || 854 (comp->left()->BindsToConstantNull() ||
854 comp->right()->BindsToConstantNull())) { 855 comp->right()->BindsToConstantNull())) {
855 branch = new BranchInstr(new StrictCompareInstr( 856 branch = new BranchInstr(new StrictCompareInstr(
856 comp->token_pos(), 857 comp->token_pos(),
857 (comp->kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT, 858 (comp->kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT,
858 comp->left(), 859 comp->left(),
859 comp->right())); 860 comp->right(),
861 false)); // No number check.
860 } else { 862 } else {
861 branch = new BranchInstr(comp, FLAG_enable_type_checks); 863 branch = new BranchInstr(comp, FLAG_enable_type_checks);
862 } 864 }
863 AddInstruction(branch); 865 AddInstruction(branch);
864 CloseFragment(); 866 CloseFragment();
865 true_successor_addresses_.Add(branch->true_successor_address()); 867 true_successor_addresses_.Add(branch->true_successor_address());
866 false_successor_addresses_.Add(branch->false_successor_address()); 868 false_successor_addresses_.Add(branch->false_successor_address());
867 } 869 }
868 870
869 871
870 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateInstr* neg) { 872 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateInstr* neg) {
871 ASSERT(!FLAG_enable_type_checks); 873 ASSERT(!FLAG_enable_type_checks);
872 Value* constant_true = Bind(new ConstantInstr(Bool::True())); 874 Value* constant_true = Bind(new ConstantInstr(Bool::True()));
873 StrictCompareInstr* comp = 875 StrictCompareInstr* comp =
874 new StrictCompareInstr(condition_token_pos(), 876 new StrictCompareInstr(condition_token_pos(),
875 Token::kNE_STRICT, 877 Token::kNE_STRICT,
876 neg->value(), 878 neg->value(),
877 constant_true); 879 constant_true,
878 comp->set_needs_number_check(false); 880 false); // No number check.
879 BranchInstr* branch = new BranchInstr(comp); 881 BranchInstr* branch = new BranchInstr(comp);
880 AddInstruction(branch); 882 AddInstruction(branch);
881 CloseFragment(); 883 CloseFragment();
882 true_successor_addresses_.Add(branch->true_successor_address()); 884 true_successor_addresses_.Add(branch->true_successor_address());
883 false_successor_addresses_.Add(branch->false_successor_address()); 885 false_successor_addresses_.Add(branch->false_successor_address());
884 } 886 }
885 887
886 888
887 void TestGraphVisitor::ReturnDefinition(Definition* definition) { 889 void TestGraphVisitor::ReturnDefinition(Definition* definition) {
888 ComparisonInstr* comp = definition->AsComparison(); 890 ComparisonInstr* comp = definition->AsComparison();
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
1194 if (FLAG_enable_type_checks) { 1196 if (FLAG_enable_type_checks) {
1195 right_value = 1197 right_value =
1196 for_right.Bind(new AssertBooleanInstr(node->right()->token_pos(), 1198 for_right.Bind(new AssertBooleanInstr(node->right()->token_pos(),
1197 right_value)); 1199 right_value));
1198 } 1200 }
1199 Value* constant_true = for_right.Bind(new ConstantInstr(Bool::True())); 1201 Value* constant_true = for_right.Bind(new ConstantInstr(Bool::True()));
1200 Value* compare = 1202 Value* compare =
1201 for_right.Bind(new StrictCompareInstr(node->token_pos(), 1203 for_right.Bind(new StrictCompareInstr(node->token_pos(),
1202 Token::kEQ_STRICT, 1204 Token::kEQ_STRICT,
1203 right_value, 1205 right_value,
1204 constant_true)); 1206 constant_true,
1207 false)); // No number check.
1205 for_right.Do(BuildStoreExprTemp(compare)); 1208 for_right.Do(BuildStoreExprTemp(compare));
1206 1209
1207 if (node->kind() == Token::kAND) { 1210 if (node->kind() == Token::kAND) {
1208 ValueGraphVisitor for_false(owner()); 1211 ValueGraphVisitor for_false(owner());
1209 Value* constant_false = for_false.Bind(new ConstantInstr(Bool::False())); 1212 Value* constant_false = for_false.Bind(new ConstantInstr(Bool::False()));
1210 for_false.Do(BuildStoreExprTemp(constant_false)); 1213 for_false.Do(BuildStoreExprTemp(constant_false));
1211 Join(for_test, for_right, for_false); 1214 Join(for_test, for_right, for_false);
1212 } else { 1215 } else {
1213 ASSERT(node->kind() == Token::kOR); 1216 ASSERT(node->kind() == Token::kOR);
1214 ValueGraphVisitor for_true(owner()); 1217 ValueGraphVisitor for_true(owner());
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
1529 intptr_t token_pos) { 1532 intptr_t token_pos) {
1530 ValueGraphVisitor for_left_value(owner()); 1533 ValueGraphVisitor for_left_value(owner());
1531 left->Visit(&for_left_value); 1534 left->Visit(&for_left_value);
1532 Append(for_left_value); 1535 Append(for_left_value);
1533 ValueGraphVisitor for_right_value(owner()); 1536 ValueGraphVisitor for_right_value(owner());
1534 right->Visit(&for_right_value); 1537 right->Visit(&for_right_value);
1535 Append(for_right_value); 1538 Append(for_right_value);
1536 StrictCompareInstr* comp = new StrictCompareInstr(token_pos, 1539 StrictCompareInstr* comp = new StrictCompareInstr(token_pos,
1537 kind, 1540 kind,
1538 for_left_value.value(), 1541 for_left_value.value(),
1539 for_right_value.value()); 1542 for_right_value.value(),
1543 true); // Number check.
1540 return comp; 1544 return comp;
1541 } 1545 }
1542 1546
1543 1547
1544 // <Expression> :: Comparison { kind: Token::Kind 1548 // <Expression> :: Comparison { kind: Token::Kind
1545 // left: <Expression> 1549 // left: <Expression>
1546 // right: <Expression> } 1550 // right: <Expression> }
1547 // TODO(srdjan): Implement new equality. 1551 // TODO(srdjan): Implement new equality.
1548 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { 1552 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) {
1549 if (Token::IsTypeTestOperator(node->kind())) { 1553 if (Token::IsTypeTestOperator(node->kind())) {
(...skipping 1533 matching lines...) Expand 10 before | Expand all | Expand 10 after
3083 const Function& function = owner()->parsed_function()->function(); 3087 const Function& function = owner()->parsed_function()->function();
3084 if (!function.IsClosureFunction()) { 3088 if (!function.IsClosureFunction()) {
3085 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function); 3089 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function);
3086 switch (kind) { 3090 switch (kind) {
3087 case MethodRecognizer::kObjectEquals: { 3091 case MethodRecognizer::kObjectEquals: {
3088 Value* receiver = Bind(BuildLoadThisVar(node->scope())); 3092 Value* receiver = Bind(BuildLoadThisVar(node->scope()));
3089 LocalVariable* other_var = 3093 LocalVariable* other_var =
3090 node->scope()->LookupVariable(Symbols::Other(), 3094 node->scope()->LookupVariable(Symbols::Other(),
3091 true); // Test only. 3095 true); // Test only.
3092 Value* other = Bind(new LoadLocalInstr(*other_var)); 3096 Value* other = Bind(new LoadLocalInstr(*other_var));
3097 // Receiver is not a number because numbers override equality.
3098 const bool kNoNumberCheck = false;
3093 StrictCompareInstr* compare = 3099 StrictCompareInstr* compare =
3094 new StrictCompareInstr(node->token_pos(), 3100 new StrictCompareInstr(node->token_pos(),
3095 Token::kEQ_STRICT, 3101 Token::kEQ_STRICT,
3096 receiver, 3102 receiver,
3097 other); 3103 other,
3098 // Receiver is not a number because numbers override equality. 3104 kNoNumberCheck);
3099 compare->set_needs_number_check(false);
3100 return ReturnDefinition(compare); 3105 return ReturnDefinition(compare);
3101 } 3106 }
3102 case MethodRecognizer::kStringBaseLength: 3107 case MethodRecognizer::kStringBaseLength:
3103 case MethodRecognizer::kStringBaseIsEmpty: { 3108 case MethodRecognizer::kStringBaseIsEmpty: {
3104 Value* receiver = Bind(BuildLoadThisVar(node->scope())); 3109 Value* receiver = Bind(BuildLoadThisVar(node->scope()));
3105 // Treat length loads as mutable (i.e. affected by side effects) to 3110 // Treat length loads as mutable (i.e. affected by side effects) to
3106 // avoid hoisting them since we can't hoist the preceding class-check. 3111 // avoid hoisting them since we can't hoist the preceding class-check.
3107 // This is because of externalization of strings that affects their 3112 // This is because of externalization of strings that affects their
3108 // class-id. 3113 // class-id.
3109 const bool is_immutable = false; 3114 const bool is_immutable = false;
3110 LoadFieldInstr* load = new LoadFieldInstr( 3115 LoadFieldInstr* load = new LoadFieldInstr(
3111 receiver, 3116 receiver,
3112 String::length_offset(), 3117 String::length_offset(),
3113 Type::ZoneHandle(Type::SmiType()), 3118 Type::ZoneHandle(Type::SmiType()),
3114 is_immutable); 3119 is_immutable);
3115 load->set_result_cid(kSmiCid); 3120 load->set_result_cid(kSmiCid);
3116 load->set_recognized_kind(MethodRecognizer::kStringBaseLength); 3121 load->set_recognized_kind(MethodRecognizer::kStringBaseLength);
3117 if (kind == MethodRecognizer::kStringBaseLength) { 3122 if (kind == MethodRecognizer::kStringBaseLength) {
3118 return ReturnDefinition(load); 3123 return ReturnDefinition(load);
3119 } 3124 }
3120 ASSERT(kind == MethodRecognizer::kStringBaseIsEmpty); 3125 ASSERT(kind == MethodRecognizer::kStringBaseIsEmpty);
3121 Value* zero_val = Bind(new ConstantInstr(Smi::ZoneHandle(Smi::New(0)))); 3126 Value* zero_val = Bind(new ConstantInstr(Smi::ZoneHandle(Smi::New(0))));
3122 Value* load_val = Bind(load); 3127 Value* load_val = Bind(load);
3123 StrictCompareInstr* compare = 3128 StrictCompareInstr* compare =
3124 new StrictCompareInstr(node->token_pos(), 3129 new StrictCompareInstr(node->token_pos(),
3125 Token::kEQ_STRICT, 3130 Token::kEQ_STRICT,
3126 load_val, 3131 load_val,
3127 zero_val); 3132 zero_val,
3133 false); // No number check.
3128 return ReturnDefinition(compare); 3134 return ReturnDefinition(compare);
3129 } 3135 }
3130 case MethodRecognizer::kGrowableArrayLength: 3136 case MethodRecognizer::kGrowableArrayLength:
3131 case MethodRecognizer::kObjectArrayLength: 3137 case MethodRecognizer::kObjectArrayLength:
3132 case MethodRecognizer::kImmutableArrayLength: 3138 case MethodRecognizer::kImmutableArrayLength:
3133 case MethodRecognizer::kTypedDataLength: { 3139 case MethodRecognizer::kTypedDataLength: {
3134 Value* receiver = Bind(BuildLoadThisVar(node->scope())); 3140 Value* receiver = Bind(BuildLoadThisVar(node->scope()));
3135 const bool is_immutable = 3141 const bool is_immutable =
3136 (kind != MethodRecognizer::kGrowableArrayLength); 3142 (kind != MethodRecognizer::kGrowableArrayLength);
3137 LoadFieldInstr* load = new LoadFieldInstr( 3143 LoadFieldInstr* load = new LoadFieldInstr(
(...skipping 896 matching lines...) Expand 10 before | Expand all | Expand 10 after
4034 LanguageError::kError, 4040 LanguageError::kError,
4035 Heap::kNew, 4041 Heap::kNew,
4036 "FlowGraphBuilder Bailout: %s %s", 4042 "FlowGraphBuilder Bailout: %s %s",
4037 String::Handle(function.name()).ToCString(), 4043 String::Handle(function.name()).ToCString(),
4038 reason)); 4044 reason));
4039 Isolate::Current()->long_jump_base()->Jump(1, error); 4045 Isolate::Current()->long_jump_base()->Jump(1, error);
4040 } 4046 }
4041 4047
4042 4048
4043 } // namespace dart 4049 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/compiler.cc ('k') | runtime/vm/flow_graph_compiler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698