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

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

Issue 2897603002: VM: Constant fold more loads from constants in the optimizer. (Closed)
Patch Set: Created 3 years, 7 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 | « runtime/vm/intermediate_language.h ('k') | no next file » | 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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/intermediate_language.h" 5 #include "vm/intermediate_language.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/bootstrap.h" 8 #include "vm/bootstrap.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/constant_propagator.h" 10 #include "vm/constant_propagator.h"
(...skipping 2103 matching lines...) Expand 10 before | Expand all | Expand 10 after
2114 2114
2115 2115
2116 // A math unary instruction has a side effect (exception 2116 // A math unary instruction has a side effect (exception
2117 // thrown) if the argument is not a number. 2117 // thrown) if the argument is not a number.
2118 // TODO(srdjan): eliminate if has no uses and input is guaranteed to be number. 2118 // TODO(srdjan): eliminate if has no uses and input is guaranteed to be number.
2119 Definition* MathUnaryInstr::Canonicalize(FlowGraph* flow_graph) { 2119 Definition* MathUnaryInstr::Canonicalize(FlowGraph* flow_graph) {
2120 return this; 2120 return this;
2121 } 2121 }
2122 2122
2123 2123
2124 bool LoadFieldInstr::Evaluate(const Object& instance, Object* result) {
2125 if (field() == NULL || !field()->is_final() || !instance.IsInstance()) {
2126 return false;
2127 }
2128
2129 // Check that instance really has the field which we
2130 // are trying to load from.
2131 Class& cls = Class::Handle(instance.clazz());
2132 while (cls.raw() != Class::null() && cls.raw() != field()->Owner()) {
2133 cls = cls.SuperClass();
2134 }
2135 if (cls.raw() != field()->Owner()) {
2136 // Failed to find the field in class or its superclasses.
2137 return false;
2138 }
2139
2140 // Object has the field: execute the load.
2141 *result = Instance::Cast(instance).GetField(*field());
2142 return true;
2143 }
2144
2145
2124 Definition* LoadFieldInstr::Canonicalize(FlowGraph* flow_graph) { 2146 Definition* LoadFieldInstr::Canonicalize(FlowGraph* flow_graph) {
2125 if (!HasUses()) return NULL; 2147 if (!HasUses()) return NULL;
2126 if (!IsImmutableLengthLoad()) return this;
2127 2148
2128 // For fixed length arrays if the array is the result of a known constructor 2149 if (IsImmutableLengthLoad()) {
2129 // call we can replace the length load with the length argument passed to 2150 // For fixed length arrays if the array is the result of a known constructor
2130 // the constructor. 2151 // call we can replace the length load with the length argument passed to
2131 StaticCallInstr* call = 2152 // the constructor.
2132 instance()->definition()->OriginalDefinition()->AsStaticCall(); 2153 StaticCallInstr* call =
2133 if (call != NULL) { 2154 instance()->definition()->OriginalDefinition()->AsStaticCall();
2134 if (call->is_known_list_constructor() && 2155 if (call != NULL) {
2135 IsFixedLengthArrayCid(call->Type()->ToCid())) { 2156 if (call->is_known_list_constructor() &&
2136 return call->ArgumentAt(1); 2157 IsFixedLengthArrayCid(call->Type()->ToCid())) {
2158 return call->ArgumentAt(1);
2159 }
2160 }
2161
2162 CreateArrayInstr* create_array =
2163 instance()->definition()->OriginalDefinition()->AsCreateArray();
2164 if ((create_array != NULL) &&
2165 (recognized_kind() == MethodRecognizer::kObjectArrayLength)) {
2166 return create_array->num_elements()->definition();
2167 }
2168
2169 // For arrays with guarded lengths, replace the length load
2170 // with a constant.
2171 LoadFieldInstr* load_array =
2172 instance()->definition()->OriginalDefinition()->AsLoadField();
2173 if (load_array != NULL) {
2174 const Field* field = load_array->field();
2175 if ((field != NULL) && (field->guarded_list_length() >= 0)) {
2176 return flow_graph->GetConstant(
2177 Smi::Handle(Smi::New(field->guarded_list_length())));
2178 }
2137 } 2179 }
2138 } 2180 }
2139 2181
2140 CreateArrayInstr* create_array = 2182 // Try folding away loads from constant objects.
2141 instance()->definition()->OriginalDefinition()->AsCreateArray(); 2183 if (instance()->BindsToConstant()) {
2142 if ((create_array != NULL) && 2184 Object& result = Object::Handle();
2143 (recognized_kind() == MethodRecognizer::kObjectArrayLength)) { 2185 if (Evaluate(instance()->BoundConstant(), &result)) {
2144 return create_array->num_elements()->definition(); 2186 return flow_graph->GetConstant(result);
2187 }
2145 } 2188 }
2146 2189
2147 // For arrays with guarded lengths, replace the length load
2148 // with a constant.
2149 LoadFieldInstr* load_array =
2150 instance()->definition()->OriginalDefinition()->AsLoadField();
2151 if (load_array != NULL) {
2152 const Field* field = load_array->field();
2153 if ((field != NULL) && (field->guarded_list_length() >= 0)) {
2154 return flow_graph->GetConstant(
2155 Smi::Handle(Smi::New(field->guarded_list_length())));
2156 }
2157 }
2158 return this; 2190 return this;
2159 } 2191 }
2160 2192
2161 2193
2162 Definition* AssertBooleanInstr::Canonicalize(FlowGraph* flow_graph) { 2194 Definition* AssertBooleanInstr::Canonicalize(FlowGraph* flow_graph) {
2163 if (FLAG_eliminate_type_checks && (value()->Type()->ToCid() == kBoolCid)) { 2195 if (FLAG_eliminate_type_checks && (value()->Type()->ToCid() == kBoolCid)) {
2164 return value()->definition(); 2196 return value()->definition();
2165 } 2197 }
2166 2198
2167 return this; 2199 return this;
(...skipping 2140 matching lines...) Expand 10 before | Expand all | Expand 10 after
4308 "native function '%s' (%" Pd " arguments) cannot be found", 4340 "native function '%s' (%" Pd " arguments) cannot be found",
4309 native_name().ToCString(), function().NumParameters()); 4341 native_name().ToCString(), function().NumParameters());
4310 } 4342 }
4311 set_is_auto_scope(auto_setup_scope); 4343 set_is_auto_scope(auto_setup_scope);
4312 set_native_c_function(native_function); 4344 set_native_c_function(native_function);
4313 } 4345 }
4314 4346
4315 #undef __ 4347 #undef __
4316 4348
4317 } // namespace dart 4349 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698