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

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

Issue 2897803002: 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') | runtime/vm/precompiler.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) 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 2107 matching lines...) Expand 10 before | Expand all | Expand 10 after
2118 2118
2119 2119
2120 // A math unary instruction has a side effect (exception 2120 // A math unary instruction has a side effect (exception
2121 // thrown) if the argument is not a number. 2121 // thrown) if the argument is not a number.
2122 // TODO(srdjan): eliminate if has no uses and input is guaranteed to be number. 2122 // TODO(srdjan): eliminate if has no uses and input is guaranteed to be number.
2123 Definition* MathUnaryInstr::Canonicalize(FlowGraph* flow_graph) { 2123 Definition* MathUnaryInstr::Canonicalize(FlowGraph* flow_graph) {
2124 return this; 2124 return this;
2125 } 2125 }
2126 2126
2127 2127
2128 bool LoadFieldInstr::Evaluate(const Object& instance, Object* result) {
2129 if (field() == NULL || !field()->is_final() || !instance.IsInstance()) {
2130 return false;
2131 }
2132
2133 // Check that instance really has the field which we
2134 // are trying to load from.
2135 Class& cls = Class::Handle(instance.clazz());
2136 while (cls.raw() != Class::null() && cls.raw() != field()->Owner()) {
2137 cls = cls.SuperClass();
2138 }
2139 if (cls.raw() != field()->Owner()) {
2140 // Failed to find the field in class or its superclasses.
2141 return false;
2142 }
2143
2144 // Object has the field: execute the load.
2145 *result = Instance::Cast(instance).GetField(*field());
2146 return true;
2147 }
2148
2149
2128 Definition* LoadFieldInstr::Canonicalize(FlowGraph* flow_graph) { 2150 Definition* LoadFieldInstr::Canonicalize(FlowGraph* flow_graph) {
2129 if (!HasUses()) return NULL; 2151 if (!HasUses()) return NULL;
2130 if (!IsImmutableLengthLoad()) return this;
2131 2152
2132 // For fixed length arrays if the array is the result of a known constructor 2153 if (IsImmutableLengthLoad()) {
2133 // call we can replace the length load with the length argument passed to 2154 // For fixed length arrays if the array is the result of a known constructor
2134 // the constructor. 2155 // call we can replace the length load with the length argument passed to
2135 StaticCallInstr* call = 2156 // the constructor.
2136 instance()->definition()->OriginalDefinition()->AsStaticCall(); 2157 StaticCallInstr* call =
2137 if (call != NULL) { 2158 instance()->definition()->OriginalDefinition()->AsStaticCall();
2138 if (call->is_known_list_constructor() && 2159 if (call != NULL) {
2139 IsFixedLengthArrayCid(call->Type()->ToCid())) { 2160 if (call->is_known_list_constructor() &&
2140 return call->ArgumentAt(1); 2161 IsFixedLengthArrayCid(call->Type()->ToCid())) {
2162 return call->ArgumentAt(1);
2163 }
2164 }
2165
2166 CreateArrayInstr* create_array =
2167 instance()->definition()->OriginalDefinition()->AsCreateArray();
2168 if ((create_array != NULL) &&
2169 (recognized_kind() == MethodRecognizer::kObjectArrayLength)) {
2170 return create_array->num_elements()->definition();
2171 }
2172
2173 // For arrays with guarded lengths, replace the length load
2174 // with a constant.
2175 LoadFieldInstr* load_array =
2176 instance()->definition()->OriginalDefinition()->AsLoadField();
2177 if (load_array != NULL) {
2178 const Field* field = load_array->field();
2179 if ((field != NULL) && (field->guarded_list_length() >= 0)) {
2180 return flow_graph->GetConstant(
2181 Smi::Handle(Smi::New(field->guarded_list_length())));
2182 }
2141 } 2183 }
2142 } 2184 }
2143 2185
2144 CreateArrayInstr* create_array = 2186 // Try folding away loads from constant objects.
2145 instance()->definition()->OriginalDefinition()->AsCreateArray(); 2187 if (instance()->BindsToConstant()) {
2146 if ((create_array != NULL) && 2188 Object& result = Object::Handle();
2147 (recognized_kind() == MethodRecognizer::kObjectArrayLength)) { 2189 if (Evaluate(instance()->BoundConstant(), &result)) {
2148 return create_array->num_elements()->definition(); 2190 return flow_graph->GetConstant(result);
2191 }
2149 } 2192 }
2150 2193
2151 // For arrays with guarded lengths, replace the length load
2152 // with a constant.
2153 LoadFieldInstr* load_array =
2154 instance()->definition()->OriginalDefinition()->AsLoadField();
2155 if (load_array != NULL) {
2156 const Field* field = load_array->field();
2157 if ((field != NULL) && (field->guarded_list_length() >= 0)) {
2158 return flow_graph->GetConstant(
2159 Smi::Handle(Smi::New(field->guarded_list_length())));
2160 }
2161 }
2162 return this; 2194 return this;
2163 } 2195 }
2164 2196
2165 2197
2166 Definition* AssertBooleanInstr::Canonicalize(FlowGraph* flow_graph) { 2198 Definition* AssertBooleanInstr::Canonicalize(FlowGraph* flow_graph) {
2167 if (FLAG_eliminate_type_checks && (value()->Type()->ToCid() == kBoolCid)) { 2199 if (FLAG_eliminate_type_checks && (value()->Type()->ToCid() == kBoolCid)) {
2168 return value()->definition(); 2200 return value()->definition();
2169 } 2201 }
2170 2202
2171 return this; 2203 return this;
(...skipping 2123 matching lines...) Expand 10 before | Expand all | Expand 10 after
4295 "native function '%s' (%" Pd " arguments) cannot be found", 4327 "native function '%s' (%" Pd " arguments) cannot be found",
4296 native_name().ToCString(), function().NumParameters()); 4328 native_name().ToCString(), function().NumParameters());
4297 } 4329 }
4298 set_is_auto_scope(auto_setup_scope); 4330 set_is_auto_scope(auto_setup_scope);
4299 set_native_c_function(native_function); 4331 set_native_c_function(native_function);
4300 } 4332 }
4301 4333
4302 #undef __ 4334 #undef __
4303 4335
4304 } // namespace dart 4336 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/precompiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698