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

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

Issue 27192005: Add new style of string interpolation optimization: new nodes, working constant folding. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 2 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 | Annotate | Revision Log
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/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/dart_entry.h" 9 #include "vm/dart_entry.h"
10 #include "vm/flow_graph_builder.h" 10 #include "vm/flow_graph_builder.h"
(...skipping 6198 matching lines...) Expand 10 before | Expand all | Expand 10 after
6209 SetValue(instr, non_constant_); 6209 SetValue(instr, non_constant_);
6210 } 6210 }
6211 6211
6212 6212
6213 void ConstantPropagator::VisitStringFromCharCode( 6213 void ConstantPropagator::VisitStringFromCharCode(
6214 StringFromCharCodeInstr* instr) { 6214 StringFromCharCodeInstr* instr) {
6215 SetValue(instr, non_constant_); 6215 SetValue(instr, non_constant_);
6216 } 6216 }
6217 6217
6218 6218
6219 void ConstantPropagator::VisitStringInterpolate(StringInterpolateInstr* instr) {
6220 if (IsNonConstant(instr->constant_value())) {
6221 // Do not bother with costly analysis if we already know that the
6222 // instruction is not a constant.
6223 SetValue(instr, non_constant_);
6224 return;
6225 }
6226 // If all inputs are constant strings, numbers, booleans or null, then
6227 // constant fold.
6228 // TODO(srdjan): Also constant fold an interval of constant arguments.
6229 // v2 <- CreateArray(v0)
6230 // StoreIndexed(v2, v3, v4) -- v3:constant index, v4: value.
6231 // ..
6232 // v8 <- StaticCall(_interpolate, v2)
Kevin Millikin (Google) 2013/10/16 15:14:03 This is not StaticCall anymore.
srdjan 2013/10/16 17:46:37 v8 <- StringInterpolate(v2)
6233 CreateArrayInstr* create_array =
6234 instr->value()->definition()->AsCreateArray();
6235 ASSERT(create_array != NULL);
6236
6237 // Check if the string interpolation has only constant inputs.
6238 for (Value::Iterator it(create_array->input_use_list());
6239 !it.Done();
6240 it.Advance()) {
6241 Instruction* curr = it.Current()->instruction();
6242 if (curr != instr) {
6243 StoreIndexedInstr* store = curr->AsStoreIndexed();
6244 ASSERT(store != NULL);
6245 if (!IsConstant(store->value()->definition()->constant_value())) {
6246 // Unknown or non-constant.
6247 SetValue(instr, store->value()->definition()->constant_value());
Kevin Millikin (Google) 2013/10/16 15:14:03 This is the only place where we potentially call S
srdjan 2013/10/16 17:46:37 Done.
6248 return;
6249 }
6250 }
6251 }
6252 // Interpolate string at compile time.
6253 const Array& value_arr =
6254 Array::Handle(Array::New(create_array->num_elements()));
6255 // Build array of literal values to interpolate.
6256 for (Value::Iterator it(create_array->input_use_list());
6257 !it.Done();
6258 it.Advance()) {
6259 Instruction* curr = it.Current()->instruction();
6260 // Skip StringInterpolateInstr.
6261 if (curr != instr) {
6262 StoreIndexedInstr* store = curr->AsStoreIndexed();
6263 ASSERT(store != NULL);
6264 Value* index_value = store->index();
6265 ASSERT(index_value->BindsToConstant() && index_value->IsSmiValue());
6266 const intptr_t ix = Smi::Cast(index_value->BoundConstant()).Value();
6267 ASSERT(IsConstant(store->value()->definition()->constant_value()));
6268 value_arr.SetAt(ix, store->value()->definition()->constant_value());
6269 }
6270 }
6271 // Build argument array to pass to the interpolation function.
6272 const Array& interpolate_arg = Array::Handle(Array::New(1));
6273 interpolate_arg.SetAt(0, value_arr);
6274 // Call interpolation function.
6275 String& concatenated = String::ZoneHandle();
6276 concatenated ^=
6277 DartEntry::InvokeFunction(instr->CallFunction(), interpolate_arg);
6278 if (concatenated.IsUnhandledException()) {
6279 SetValue(instr, non_constant_);
6280 return;
6281 }
6282
6283 concatenated = Symbols::New(concatenated);
6284 SetValue(instr, concatenated);
6285 }
6286
6287
6219 void ConstantPropagator::VisitLoadIndexed(LoadIndexedInstr* instr) { 6288 void ConstantPropagator::VisitLoadIndexed(LoadIndexedInstr* instr) {
6220 SetValue(instr, non_constant_); 6289 SetValue(instr, non_constant_);
6221 } 6290 }
6222 6291
6223 6292
6224 void ConstantPropagator::VisitStoreIndexed(StoreIndexedInstr* instr) { 6293 void ConstantPropagator::VisitStoreIndexed(StoreIndexedInstr* instr) {
6225 SetValue(instr, instr->value()->definition()->constant_value()); 6294 SetValue(instr, instr->value()->definition()->constant_value());
6226 } 6295 }
6227 6296
6228 6297
(...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after
6981 !defn->IsStoreStaticField() && 7050 !defn->IsStoreStaticField() &&
6982 !defn->IsStoreVMField()) { 7051 !defn->IsStoreVMField()) {
6983 if (FLAG_trace_constant_propagation) { 7052 if (FLAG_trace_constant_propagation) {
6984 OS::Print("Constant v%" Pd " = %s\n", 7053 OS::Print("Constant v%" Pd " = %s\n",
6985 defn->ssa_temp_index(), 7054 defn->ssa_temp_index(),
6986 defn->constant_value().ToCString()); 7055 defn->constant_value().ToCString());
6987 } 7056 }
6988 ConstantInstr* constant = graph_->GetConstant(defn->constant_value()); 7057 ConstantInstr* constant = graph_->GetConstant(defn->constant_value());
6989 defn->ReplaceUsesWith(constant); 7058 defn->ReplaceUsesWith(constant);
6990 i.RemoveCurrentFromGraph(); 7059 i.RemoveCurrentFromGraph();
7060 if (defn->IsStringInterpolate()) {
7061 CreateArrayInstr* create_array = defn->AsStringInterpolate()->
7062 value()->definition()->AsCreateArray();
7063 for (Value* use = create_array->input_use_list();
7064 use != NULL;
7065 use = create_array->input_use_list()) {
7066 use->instruction()->RemoveFromGraph();
7067 }
7068 create_array->RemoveFromGraph();
7069 }
6991 } 7070 }
6992 } 7071 }
6993 7072
6994 // Replace branches where one target is unreachable with jumps. 7073 // Replace branches where one target is unreachable with jumps.
6995 BranchInstr* branch = block->last_instruction()->AsBranch(); 7074 BranchInstr* branch = block->last_instruction()->AsBranch();
6996 if (branch != NULL) { 7075 if (branch != NULL) {
6997 TargetEntryInstr* if_true = branch->true_successor(); 7076 TargetEntryInstr* if_true = branch->true_successor();
6998 TargetEntryInstr* if_false = branch->false_successor(); 7077 TargetEntryInstr* if_false = branch->false_successor();
6999 JoinEntryInstr* join = NULL; 7078 JoinEntryInstr* join = NULL;
7000 Instruction* next = NULL; 7079 Instruction* next = NULL;
(...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after
7666 } 7745 }
7667 7746
7668 // Insert materializations at environment uses. 7747 // Insert materializations at environment uses.
7669 for (intptr_t i = 0; i < exits.length(); i++) { 7748 for (intptr_t i = 0; i < exits.length(); i++) {
7670 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); 7749 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields);
7671 } 7750 }
7672 } 7751 }
7673 7752
7674 7753
7675 } // namespace dart 7754 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698