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

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

Issue 27006003: Cleanups, refactoring in anticipation of new string interpolation nodes. Removed unnecessary code. (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 6031 matching lines...) Expand 10 before | Expand all | Expand 10 after
6042 6042
6043 6043
6044 void ConstantPropagator::VisitPolymorphicInstanceCall( 6044 void ConstantPropagator::VisitPolymorphicInstanceCall(
6045 PolymorphicInstanceCallInstr* instr) { 6045 PolymorphicInstanceCallInstr* instr) {
6046 SetValue(instr, non_constant_); 6046 SetValue(instr, non_constant_);
6047 } 6047 }
6048 6048
6049 6049
6050 void ConstantPropagator::VisitStaticCall(StaticCallInstr* instr) { 6050 void ConstantPropagator::VisitStaticCall(StaticCallInstr* instr) {
6051 SetValue(instr, non_constant_); 6051 SetValue(instr, non_constant_);
6052 return;
6053 // TODO(srdjan): Enable code below once issues resolved.
6054 if (IsNonConstant(instr->constant_value())) {
6055 // Do not bother with costly analysis if we already know that the
6056 // instruction is not a constant.
6057 SetValue(instr, non_constant_);
6058 return;
6059 }
6060 MethodRecognizer::Kind recognized_kind =
6061 MethodRecognizer::RecognizeKind(instr->function());
6062 if (recognized_kind == MethodRecognizer::kStringBaseInterpolate) {
6063 // static String _interpolate(List values)
6064 //
6065 // Code for calling interpolate is generated by the compiler:
6066 // v2 <- CreateArray(v0)
6067 // StoreIndexed(v2, v3, v4) -- v3:constant index, v4: value.
6068 // ..
6069 // PushArgument(v2)
6070 // v8 <- StaticCall(_interpolate, v2)
6071 // Detect that all values are constant, interpolate at compile
6072 // time.
6073 ASSERT(instr->ArgumentCount() == 1);
6074 CreateArrayInstr* create_array = instr->ArgumentAt(0)->AsCreateArray();
6075 ASSERT(create_array != NULL);
6076 // Check if the string interpolation has only constant inputs.
6077 for (Value::Iterator it(create_array->input_use_list());
6078 !it.Done();
6079 it.Advance()) {
6080 Instruction* curr = it.Current()->instruction();
6081 StoreIndexedInstr* store = curr->AsStoreIndexed();
6082 // 'store' is NULL fir PushArgument instruction: skip it.
6083 if ((store != NULL) &&
6084 (IsNonConstant(store->value()->definition()->constant_value()))) {
6085 SetValue(instr, non_constant_);
6086 return;
6087 }
6088 }
6089 // Interpolate string at compile time.
6090 const Array& value_arr =
6091 Array::Handle(Array::New(create_array->num_elements()));
6092 // Build the array of literal values to interpolate, abort if a value is
6093 // not literal.
6094 for (Value::Iterator it(create_array->input_use_list());
6095 !it.Done();
6096 it.Advance()) {
6097 Instruction* curr = it.Current()->instruction();
6098 StoreIndexedInstr* store = curr->AsStoreIndexed();
6099 if (store == NULL) {
6100 ASSERT(curr == instr->PushArgumentAt(0));
6101 } else {
6102 Value* index_value = store->index();
6103 ASSERT(index_value->BindsToConstant() && index_value->IsSmiValue());
6104 const intptr_t ix = Smi::Cast(index_value->BoundConstant()).Value();
6105 ASSERT(IsConstant(store->value()->definition()->constant_value()));
6106 value_arr.SetAt(ix, store->value()->definition()->constant_value());
6107 }
6108 }
6109 // Build argument array to pass to the interpolation function.
6110 const Array& interpolate_arg = Array::Handle(Array::New(1));
6111 interpolate_arg.SetAt(0, value_arr);
6112 // Call interpolation function.
6113 String& concatenated = String::ZoneHandle();
6114 concatenated ^=
6115 DartEntry::InvokeFunction(instr->function(), interpolate_arg);
6116 if (concatenated.IsUnhandledException()) {
6117 SetValue(instr, non_constant_);
6118 return;
6119 }
6120
6121 concatenated = Symbols::New(concatenated);
6122 SetValue(instr, concatenated);
6123 } else {
6124 SetValue(instr, non_constant_);
6125 }
6126 } 6052 }
6127 6053
6128 6054
6129 void ConstantPropagator::VisitLoadLocal(LoadLocalInstr* instr) { 6055 void ConstantPropagator::VisitLoadLocal(LoadLocalInstr* instr) {
6130 // Instruction is eliminated when translating to SSA. 6056 // Instruction is eliminated when translating to SSA.
6131 UNREACHABLE(); 6057 UNREACHABLE();
6132 } 6058 }
6133 6059
6134 6060
6135 void ConstantPropagator::VisitPushTemp(PushTempInstr* instr) { 6061 void ConstantPropagator::VisitPushTemp(PushTempInstr* instr) {
(...skipping 812 matching lines...) Expand 10 before | Expand all | Expand 10 after
6948 } else { 6874 } else {
6949 // No new information: Assume both targets are reachable. 6875 // No new information: Assume both targets are reachable.
6950 SetReachable(branch->true_successor()); 6876 SetReachable(branch->true_successor());
6951 SetReachable(branch->false_successor()); 6877 SetReachable(branch->false_successor());
6952 } 6878 }
6953 } 6879 }
6954 } 6880 }
6955 } 6881 }
6956 6882
6957 6883
6958 // Code for calling interpolate is generated by the compiler:
6959 // v2 <- CreateArray(v0)
6960 // StoreIndexed(v2, v3, v4) -- v3:constant index, v4: value.
6961 // ..
6962 // PushArgument(v2)
6963 // v8 <- StaticCall(_interpolate, v2)
6964 // Remove the inputs.
6965 void ConstantPropagator::RemoveInterpolationInputs(
6966 const StaticCallInstr& call) {
6967 ASSERT(call.ArgumentCount() == 1);
6968 CreateArrayInstr* create_array = call.ArgumentAt(0)->AsCreateArray();
6969 ASSERT(create_array != NULL);
6970 for (Value* use = create_array->input_use_list();
6971 use != NULL;
6972 use = create_array->input_use_list()) {
6973 use->instruction()->RemoveFromGraph();
6974 }
6975 create_array->RemoveFromGraph();
6976 }
6977
6978
6979 void ConstantPropagator::Transform() { 6884 void ConstantPropagator::Transform() {
6980 if (FLAG_trace_constant_propagation) { 6885 if (FLAG_trace_constant_propagation) {
6981 OS::Print("\n==== Before constant propagation ====\n"); 6886 OS::Print("\n==== Before constant propagation ====\n");
6982 FlowGraphPrinter printer(*graph_); 6887 FlowGraphPrinter printer(*graph_);
6983 printer.PrintBlocks(); 6888 printer.PrintBlocks();
6984 } 6889 }
6985 6890
6986 GrowableArray<PhiInstr*> redundant_phis(10); 6891 GrowableArray<PhiInstr*> redundant_phis(10);
6987 6892
6988 // We will recompute dominators, block ordering, block ids, block last 6893 // We will recompute dominators, block ordering, block ids, block last
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
7076 !defn->IsStoreStaticField() && 6981 !defn->IsStoreStaticField() &&
7077 !defn->IsStoreVMField()) { 6982 !defn->IsStoreVMField()) {
7078 if (FLAG_trace_constant_propagation) { 6983 if (FLAG_trace_constant_propagation) {
7079 OS::Print("Constant v%" Pd " = %s\n", 6984 OS::Print("Constant v%" Pd " = %s\n",
7080 defn->ssa_temp_index(), 6985 defn->ssa_temp_index(),
7081 defn->constant_value().ToCString()); 6986 defn->constant_value().ToCString());
7082 } 6987 }
7083 ConstantInstr* constant = graph_->GetConstant(defn->constant_value()); 6988 ConstantInstr* constant = graph_->GetConstant(defn->constant_value());
7084 defn->ReplaceUsesWith(constant); 6989 defn->ReplaceUsesWith(constant);
7085 i.RemoveCurrentFromGraph(); 6990 i.RemoveCurrentFromGraph();
7086 if (defn->IsStaticCall()) {
7087 MethodRecognizer::Kind recognized_kind =
7088 MethodRecognizer::RecognizeKind(defn->AsStaticCall()->function());
7089 if (recognized_kind == MethodRecognizer::kStringBaseInterpolate) {
7090 RemoveInterpolationInputs(*defn->AsStaticCall());
7091 }
7092 }
7093 } 6991 }
7094 } 6992 }
7095 6993
7096 // Replace branches where one target is unreachable with jumps. 6994 // Replace branches where one target is unreachable with jumps.
7097 BranchInstr* branch = block->last_instruction()->AsBranch(); 6995 BranchInstr* branch = block->last_instruction()->AsBranch();
7098 if (branch != NULL) { 6996 if (branch != NULL) {
7099 TargetEntryInstr* if_true = branch->true_successor(); 6997 TargetEntryInstr* if_true = branch->true_successor();
7100 TargetEntryInstr* if_false = branch->false_successor(); 6998 TargetEntryInstr* if_false = branch->false_successor();
7101 JoinEntryInstr* join = NULL; 6999 JoinEntryInstr* join = NULL;
7102 Instruction* next = NULL; 7000 Instruction* next = NULL;
(...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after
7768 } 7666 }
7769 7667
7770 // Insert materializations at environment uses. 7668 // Insert materializations at environment uses.
7771 for (intptr_t i = 0; i < exits.length(); i++) { 7669 for (intptr_t i = 0; i < exits.length(); i++) {
7772 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); 7670 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields);
7773 } 7671 }
7774 } 7672 }
7775 7673
7776 7674
7777 } // namespace dart 7675 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698