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

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

Issue 11262033: Simple array bounds check elimination on top of range analysis framework. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: address comments Created 8 years, 1 month 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/flow_graph_optimizer.h ('k') | runtime/vm/il_printer.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 (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_optimizer.h" 5 #include "vm/flow_graph_optimizer.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/cha.h" 8 #include "vm/cha.h"
9 #include "vm/flow_graph_builder.h" 9 #include "vm/flow_graph_builder.h"
10 #include "vm/flow_graph_compiler.h" 10 #include "vm/flow_graph_compiler.h"
(...skipping 10 matching lines...) Expand all
21 21
22 DECLARE_FLAG(bool, eliminate_type_checks); 22 DECLARE_FLAG(bool, eliminate_type_checks);
23 DECLARE_FLAG(bool, enable_type_checks); 23 DECLARE_FLAG(bool, enable_type_checks);
24 DEFINE_FLAG(bool, trace_optimization, false, "Print optimization details."); 24 DEFINE_FLAG(bool, trace_optimization, false, "Print optimization details.");
25 DECLARE_FLAG(bool, trace_type_check_elimination); 25 DECLARE_FLAG(bool, trace_type_check_elimination);
26 DEFINE_FLAG(bool, use_cha, true, "Use class hierarchy analysis."); 26 DEFINE_FLAG(bool, use_cha, true, "Use class hierarchy analysis.");
27 DEFINE_FLAG(bool, load_cse, true, "Use redundant load elimination."); 27 DEFINE_FLAG(bool, load_cse, true, "Use redundant load elimination.");
28 DEFINE_FLAG(bool, trace_range_analysis, false, "Trace range analysis progress"); 28 DEFINE_FLAG(bool, trace_range_analysis, false, "Trace range analysis progress");
29 DEFINE_FLAG(bool, trace_constant_propagation, false, 29 DEFINE_FLAG(bool, trace_constant_propagation, false,
30 "Print constant propagation and useless code elimination."); 30 "Print constant propagation and useless code elimination.");
31 DEFINE_FLAG(bool, array_bounds_check_elimination, true,
32 "Eliminate redundant bounds checks.");
31 33
32 34
33 void FlowGraphOptimizer::ApplyICData() { 35 void FlowGraphOptimizer::ApplyICData() {
34 VisitBlocks(); 36 VisitBlocks();
35 } 37 }
36 38
37 39
38 // Attempts to convert an instance call (IC call) using propagated class-ids, 40 // Attempts to convert an instance call (IC call) using propagated class-ids,
39 // e.g., receiver class id. 41 // e.g., receiver class id.
40 void FlowGraphOptimizer::ApplyClassIds() { 42 void FlowGraphOptimizer::ApplyClassIds() {
(...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after
908 call->ArgumentAt(0)->value(), 910 call->ArgumentAt(0)->value(),
909 field.Offset(), 911 field.Offset(),
910 AbstractType::ZoneHandle(field.type())); 912 AbstractType::ZoneHandle(field.type()));
911 call->ReplaceWith(load, current_iterator()); 913 call->ReplaceWith(load, current_iterator());
912 RemovePushArguments(call); 914 RemovePushArguments(call);
913 } 915 }
914 916
915 917
916 void FlowGraphOptimizer::InlineArrayLengthGetter(InstanceCallInstr* call, 918 void FlowGraphOptimizer::InlineArrayLengthGetter(InstanceCallInstr* call,
917 intptr_t length_offset, 919 intptr_t length_offset,
918 bool is_immutable) { 920 bool is_immutable,
921 MethodRecognizer::Kind kind) {
919 // Check receiver class. 922 // Check receiver class.
920 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy()); 923 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy());
921 924
922 LoadFieldInstr* load = new LoadFieldInstr( 925 LoadFieldInstr* load = new LoadFieldInstr(
923 call->ArgumentAt(0)->value(), 926 call->ArgumentAt(0)->value(),
924 length_offset, 927 length_offset,
925 Type::ZoneHandle(Type::SmiType()), 928 Type::ZoneHandle(Type::SmiType()),
926 is_immutable); 929 is_immutable);
927 load->set_result_cid(kSmiCid); 930 load->set_result_cid(kSmiCid);
931 load->set_recognized_kind(kind);
928 call->ReplaceWith(load, current_iterator()); 932 call->ReplaceWith(load, current_iterator());
929 RemovePushArguments(call); 933 RemovePushArguments(call);
930 } 934 }
931 935
932 936
933 void FlowGraphOptimizer::InlineGArrayCapacityGetter(InstanceCallInstr* call) { 937 void FlowGraphOptimizer::InlineGArrayCapacityGetter(InstanceCallInstr* call) {
934 // Check receiver class. 938 // Check receiver class.
935 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy()); 939 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy());
936 940
937 // TODO(srdjan): type of load should be GrowableObjectArrayType. 941 // TODO(srdjan): type of load should be GrowableObjectArrayType.
938 LoadFieldInstr* data_load = new LoadFieldInstr( 942 LoadFieldInstr* data_load = new LoadFieldInstr(
939 call->ArgumentAt(0)->value(), 943 call->ArgumentAt(0)->value(),
940 Array::data_offset(), 944 Array::data_offset(),
941 Type::ZoneHandle(Type::DynamicType())); 945 Type::ZoneHandle(Type::DynamicType()));
942 data_load->set_result_cid(kArrayCid); 946 data_load->set_result_cid(kArrayCid);
943 InsertBefore(call, data_load, NULL, Definition::kValue); 947 InsertBefore(call, data_load, NULL, Definition::kValue);
944 948
945 LoadFieldInstr* length_load = new LoadFieldInstr( 949 LoadFieldInstr* length_load = new LoadFieldInstr(
946 new Value(data_load), 950 new Value(data_load),
947 Array::length_offset(), 951 Array::length_offset(),
948 Type::ZoneHandle(Type::SmiType())); 952 Type::ZoneHandle(Type::SmiType()));
949 length_load->set_result_cid(kSmiCid); 953 length_load->set_result_cid(kSmiCid);
954 length_load->set_recognized_kind(MethodRecognizer::kObjectArrayLength);
950 955
951 call->ReplaceWith(length_load, current_iterator()); 956 call->ReplaceWith(length_load, current_iterator());
952 RemovePushArguments(call); 957 RemovePushArguments(call);
953 } 958 }
954 959
955 960
956 static LoadFieldInstr* BuildLoadStringLength(Value* str) { 961 static LoadFieldInstr* BuildLoadStringLength(Value* str) {
957 const bool is_immutable = true; // String length is immutable. 962 const bool is_immutable = true; // String length is immutable.
958 LoadFieldInstr* load = new LoadFieldInstr( 963 LoadFieldInstr* load = new LoadFieldInstr(
959 str, 964 str,
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1020 if ((recognized_kind == MethodRecognizer::kObjectArrayLength) || 1025 if ((recognized_kind == MethodRecognizer::kObjectArrayLength) ||
1021 (recognized_kind == MethodRecognizer::kImmutableArrayLength) || 1026 (recognized_kind == MethodRecognizer::kImmutableArrayLength) ||
1022 (recognized_kind == MethodRecognizer::kGrowableArrayLength)) { 1027 (recognized_kind == MethodRecognizer::kGrowableArrayLength)) {
1023 if (!ic_data.HasOneTarget()) { 1028 if (!ic_data.HasOneTarget()) {
1024 // TODO(srdjan): Implement for mutiple targets. 1029 // TODO(srdjan): Implement for mutiple targets.
1025 return false; 1030 return false;
1026 } 1031 }
1027 switch (recognized_kind) { 1032 switch (recognized_kind) {
1028 case MethodRecognizer::kObjectArrayLength: 1033 case MethodRecognizer::kObjectArrayLength:
1029 case MethodRecognizer::kImmutableArrayLength: 1034 case MethodRecognizer::kImmutableArrayLength:
1030 InlineArrayLengthGetter(call, Array::length_offset(), true); 1035 InlineArrayLengthGetter(call,
1036 Array::length_offset(),
1037 true,
1038 recognized_kind);
1031 break; 1039 break;
1032 case MethodRecognizer::kGrowableArrayLength: 1040 case MethodRecognizer::kGrowableArrayLength:
1033 InlineArrayLengthGetter(call, 1041 InlineArrayLengthGetter(call,
1034 GrowableObjectArray::length_offset(), 1042 GrowableObjectArray::length_offset(),
1035 false); 1043 false,
1044 recognized_kind);
1036 break; 1045 break;
1037 default: 1046 default:
1038 UNREACHABLE(); 1047 UNREACHABLE();
1039 } 1048 }
1040 return true; 1049 return true;
1041 } 1050 }
1042 1051
1043 if (recognized_kind == MethodRecognizer::kGrowableArrayCapacity) { 1052 if (recognized_kind == MethodRecognizer::kGrowableArrayCapacity) {
1044 InlineGArrayCapacityGetter(call); 1053 InlineGArrayCapacityGetter(call);
1045 return true; 1054 return true;
(...skipping 1047 matching lines...) Expand 10 before | Expand all | Expand 10 after
2093 continue; 2102 continue;
2094 } 2103 }
2095 } 2104 }
2096 2105
2097 phi->InferRange(); 2106 phi->InferRange();
2098 } 2107 }
2099 } 2108 }
2100 } 2109 }
2101 2110
2102 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { 2111 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
2103 Definition* defn = it.Current()->AsDefinition(); 2112 Instruction* current = it.Current();
2113
2114 Definition* defn = current->AsDefinition();
2104 if ((defn != NULL) && 2115 if ((defn != NULL) &&
2105 (defn->ssa_temp_index() != -1) && 2116 (defn->ssa_temp_index() != -1) &&
2106 smi_definitions_->Contains(defn->ssa_temp_index())) { 2117 smi_definitions_->Contains(defn->ssa_temp_index())) {
2107 defn->InferRange(); 2118 defn->InferRange();
2119 } else if (FLAG_array_bounds_check_elimination &&
2120 current->IsCheckArrayBound() &&
2121 current->AsCheckArrayBound()->IsRedundant()) {
2122 it.RemoveCurrentFromGraph();
2108 } 2123 }
2109 } 2124 }
2110 2125
2111 for (intptr_t i = 0; i < block->dominated_blocks().length(); ++i) { 2126 for (intptr_t i = 0; i < block->dominated_blocks().length(); ++i) {
2112 InferRangesRecursive(block->dominated_blocks()[i]); 2127 InferRangesRecursive(block->dominated_blocks()[i]);
2113 } 2128 }
2114 } 2129 }
2115 2130
2116 2131
2117 void RangeAnalysis::InferRanges() { 2132 void RangeAnalysis::InferRanges() {
(...skipping 1421 matching lines...) Expand 10 before | Expand all | Expand 10 after
3539 3554
3540 if (FLAG_trace_constant_propagation) { 3555 if (FLAG_trace_constant_propagation) {
3541 OS::Print("\n==== After constant propagation ====\n"); 3556 OS::Print("\n==== After constant propagation ====\n");
3542 FlowGraphPrinter printer(*graph_); 3557 FlowGraphPrinter printer(*graph_);
3543 printer.PrintBlocks(); 3558 printer.PrintBlocks();
3544 } 3559 }
3545 } 3560 }
3546 3561
3547 3562
3548 } // namespace dart 3563 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/il_printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698