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

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: 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
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 897 matching lines...) Expand 10 before | Expand all | Expand 10 after
908 call->ArgumentAt(0)->value(), 908 call->ArgumentAt(0)->value(),
909 field.Offset(), 909 field.Offset(),
910 AbstractType::ZoneHandle(field.type())); 910 AbstractType::ZoneHandle(field.type()));
911 call->ReplaceWith(load, current_iterator()); 911 call->ReplaceWith(load, current_iterator());
912 RemovePushArguments(call); 912 RemovePushArguments(call);
913 } 913 }
914 914
915 915
916 void FlowGraphOptimizer::InlineArrayLengthGetter(InstanceCallInstr* call, 916 void FlowGraphOptimizer::InlineArrayLengthGetter(InstanceCallInstr* call,
917 intptr_t length_offset, 917 intptr_t length_offset,
918 bool is_immutable) { 918 bool is_immutable,
919 MethodRecognizer::Kind kind) {
919 // Check receiver class. 920 // Check receiver class.
920 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy()); 921 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy());
921 922
922 LoadFieldInstr* load = new LoadFieldInstr( 923 LoadFieldInstr* load = new LoadFieldInstr(
923 call->ArgumentAt(0)->value(), 924 call->ArgumentAt(0)->value(),
924 length_offset, 925 length_offset,
925 Type::ZoneHandle(Type::SmiType()), 926 Type::ZoneHandle(Type::SmiType()),
926 is_immutable); 927 is_immutable);
927 load->set_result_cid(kSmiCid); 928 load->set_result_cid(kSmiCid);
929 load->set_recognized_kind(kind);
928 call->ReplaceWith(load, current_iterator()); 930 call->ReplaceWith(load, current_iterator());
929 RemovePushArguments(call); 931 RemovePushArguments(call);
930 } 932 }
931 933
932 934
933 void FlowGraphOptimizer::InlineGArrayCapacityGetter(InstanceCallInstr* call) { 935 void FlowGraphOptimizer::InlineGArrayCapacityGetter(InstanceCallInstr* call) {
934 // Check receiver class. 936 // Check receiver class.
935 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy()); 937 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy());
936 938
937 // TODO(srdjan): type of load should be GrowableObjectArrayType. 939 // TODO(srdjan): type of load should be GrowableObjectArrayType.
938 LoadFieldInstr* data_load = new LoadFieldInstr( 940 LoadFieldInstr* data_load = new LoadFieldInstr(
939 call->ArgumentAt(0)->value(), 941 call->ArgumentAt(0)->value(),
940 Array::data_offset(), 942 Array::data_offset(),
941 Type::ZoneHandle(Type::DynamicType())); 943 Type::ZoneHandle(Type::DynamicType()));
942 data_load->set_result_cid(kArrayCid); 944 data_load->set_result_cid(kArrayCid);
943 InsertBefore(call, data_load, NULL, Definition::kValue); 945 InsertBefore(call, data_load, NULL, Definition::kValue);
944 946
945 LoadFieldInstr* length_load = new LoadFieldInstr( 947 LoadFieldInstr* length_load = new LoadFieldInstr(
946 new Value(data_load), 948 new Value(data_load),
947 Array::length_offset(), 949 Array::length_offset(),
948 Type::ZoneHandle(Type::SmiType())); 950 Type::ZoneHandle(Type::SmiType()));
949 length_load->set_result_cid(kSmiCid); 951 length_load->set_result_cid(kSmiCid);
952 length_load->set_recognized_kind(MethodRecognizer::kObjectArrayLength);
950 953
951 call->ReplaceWith(length_load, current_iterator()); 954 call->ReplaceWith(length_load, current_iterator());
952 RemovePushArguments(call); 955 RemovePushArguments(call);
953 } 956 }
954 957
955 958
956 static LoadFieldInstr* BuildLoadStringLength(Value* str) { 959 static LoadFieldInstr* BuildLoadStringLength(Value* str) {
957 const bool is_immutable = true; // String length is immutable. 960 const bool is_immutable = true; // String length is immutable.
958 LoadFieldInstr* load = new LoadFieldInstr( 961 LoadFieldInstr* load = new LoadFieldInstr(
959 str, 962 str,
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1020 if ((recognized_kind == MethodRecognizer::kObjectArrayLength) || 1023 if ((recognized_kind == MethodRecognizer::kObjectArrayLength) ||
1021 (recognized_kind == MethodRecognizer::kImmutableArrayLength) || 1024 (recognized_kind == MethodRecognizer::kImmutableArrayLength) ||
1022 (recognized_kind == MethodRecognizer::kGrowableArrayLength)) { 1025 (recognized_kind == MethodRecognizer::kGrowableArrayLength)) {
1023 if (!ic_data.HasOneTarget()) { 1026 if (!ic_data.HasOneTarget()) {
1024 // TODO(srdjan): Implement for mutiple targets. 1027 // TODO(srdjan): Implement for mutiple targets.
1025 return false; 1028 return false;
1026 } 1029 }
1027 switch (recognized_kind) { 1030 switch (recognized_kind) {
1028 case MethodRecognizer::kObjectArrayLength: 1031 case MethodRecognizer::kObjectArrayLength:
1029 case MethodRecognizer::kImmutableArrayLength: 1032 case MethodRecognizer::kImmutableArrayLength:
1030 InlineArrayLengthGetter(call, Array::length_offset(), true); 1033 InlineArrayLengthGetter(call,
1034 Array::length_offset(),
1035 true,
1036 recognized_kind);
1031 break; 1037 break;
1032 case MethodRecognizer::kGrowableArrayLength: 1038 case MethodRecognizer::kGrowableArrayLength:
1033 InlineArrayLengthGetter(call, 1039 InlineArrayLengthGetter(call,
1034 GrowableObjectArray::length_offset(), 1040 GrowableObjectArray::length_offset(),
1035 false); 1041 false,
1042 recognized_kind);
1036 break; 1043 break;
1037 default: 1044 default:
1038 UNREACHABLE(); 1045 UNREACHABLE();
1039 } 1046 }
1040 return true; 1047 return true;
1041 } 1048 }
1042 1049
1043 if (recognized_kind == MethodRecognizer::kGrowableArrayCapacity) { 1050 if (recognized_kind == MethodRecognizer::kGrowableArrayCapacity) {
1044 InlineGArrayCapacityGetter(call); 1051 InlineGArrayCapacityGetter(call);
1045 return true; 1052 return true;
(...skipping 1047 matching lines...) Expand 10 before | Expand all | Expand 10 after
2093 continue; 2100 continue;
2094 } 2101 }
2095 } 2102 }
2096 2103
2097 phi->InferRange(); 2104 phi->InferRange();
2098 } 2105 }
2099 } 2106 }
2100 } 2107 }
2101 2108
2102 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { 2109 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
2103 Definition* defn = it.Current()->AsDefinition(); 2110 Instruction* current = it.Current();
2111
2112 Definition* defn = current->AsDefinition();
2104 if ((defn != NULL) && 2113 if ((defn != NULL) &&
2105 (defn->ssa_temp_index() != -1) && 2114 (defn->ssa_temp_index() != -1) &&
2106 smi_definitions_->Contains(defn->ssa_temp_index())) { 2115 smi_definitions_->Contains(defn->ssa_temp_index())) {
2107 defn->InferRange(); 2116 defn->InferRange();
2117 } else if (current->IsCheckArrayBound() &&
2118 current->AsCheckArrayBound()->IsRedundant()) {
2119 it.RemoveCurrentFromGraph();
2108 } 2120 }
2109 } 2121 }
2110 2122
2111 for (intptr_t i = 0; i < block->dominated_blocks().length(); ++i) { 2123 for (intptr_t i = 0; i < block->dominated_blocks().length(); ++i) {
2112 InferRangesRecursive(block->dominated_blocks()[i]); 2124 InferRangesRecursive(block->dominated_blocks()[i]);
2113 } 2125 }
2114 } 2126 }
2115 2127
2116 2128
2117 void RangeAnalysis::InferRanges() { 2129 void RangeAnalysis::InferRanges() {
(...skipping 1421 matching lines...) Expand 10 before | Expand all | Expand 10 after
3539 3551
3540 if (FLAG_trace_constant_propagation) { 3552 if (FLAG_trace_constant_propagation) {
3541 OS::Print("\n==== After constant propagation ====\n"); 3553 OS::Print("\n==== After constant propagation ====\n");
3542 FlowGraphPrinter printer(*graph_); 3554 FlowGraphPrinter printer(*graph_);
3543 printer.PrintBlocks(); 3555 printer.PrintBlocks();
3544 } 3556 }
3545 } 3557 }
3546 3558
3547 3559
3548 } // namespace dart 3560 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698