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

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

Issue 104893003: For instance call representing numerical comparisons (double and Smi for now) that were never visit… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years 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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 return FLAG_enable_simd_inline; 55 return FLAG_enable_simd_inline;
56 } 56 }
57 57
58 58
59 // Optimize instance calls using ICData. 59 // Optimize instance calls using ICData.
60 void FlowGraphOptimizer::ApplyICData() { 60 void FlowGraphOptimizer::ApplyICData() {
61 VisitBlocks(); 61 VisitBlocks();
62 } 62 }
63 63
64 64
65 // Optimize instance calls using cid. 65 // Optimize instance calls using cid. This is called after the optimizer which
66 // converts instance calls to instructions has been run. Any remaining
67 // instance calls probably do not have IC data.
66 // Attempts to convert an instance call (IC call) using propagated class-ids, 68 // Attempts to convert an instance call (IC call) using propagated class-ids,
67 // e.g., receiver class id, guarded-cid. 69 // e.g., receiver class id, guarded-cid.
68 void FlowGraphOptimizer::ApplyClassIds() { 70 void FlowGraphOptimizer::ApplyClassIds() {
69 ASSERT(current_iterator_ == NULL); 71 ASSERT(current_iterator_ == NULL);
70 for (intptr_t i = 0; i < block_order_.length(); ++i) { 72 for (intptr_t i = 0; i < block_order_.length(); ++i) {
71 BlockEntryInstr* entry = block_order_[i]; 73 BlockEntryInstr* entry = block_order_[i];
72 ForwardInstructionIterator it(entry); 74 ForwardInstructionIterator it(entry);
73 current_iterator_ = &it; 75 current_iterator_ = &it;
74 for (; !it.Done(); it.Advance()) { 76 for (; !it.Done(); it.Advance()) {
75 Instruction* instr = it.Current(); 77 Instruction* instr = it.Current();
(...skipping 13 matching lines...) Expand all
89 if (compare->IsStrictCompare()) { 91 if (compare->IsStrictCompare()) {
90 VisitStrictCompare(compare->AsStrictCompare()); 92 VisitStrictCompare(compare->AsStrictCompare());
91 } 93 }
92 } 94 }
93 } 95 }
94 current_iterator_ = NULL; 96 current_iterator_ = NULL;
95 } 97 }
96 } 98 }
97 99
98 100
101 // TODO(srdjan): write tests for others.
102 static bool IsNumberCid(intptr_t cid) {
103 return (cid == kSmiCid) || (cid == kDoubleCid);
104 }
105
106 static bool NoneIsDynamic(const GrowableArray<intptr_t>& cids) {
107 for (intptr_t i = 0; i < cids.length(); i++) {
108 if (cids[i] == kDynamicCid) {
109 return false;
110 }
111 }
112 return true;
113 }
114
115
99 // Attempt to build ICData for call using propagated class-ids. 116 // Attempt to build ICData for call using propagated class-ids.
100 bool FlowGraphOptimizer::TryCreateICData(InstanceCallInstr* call) { 117 bool FlowGraphOptimizer::TryCreateICData(InstanceCallInstr* call) {
101 ASSERT(call->HasICData()); 118 ASSERT(call->HasICData());
102 if (call->ic_data()->NumberOfChecks() > 0) { 119 if (call->ic_data()->NumberOfChecks() > 0) {
103 // This occurs when an instance call has too many checks. 120 // This occurs when an instance call has too many checks, will be
104 // TODO(srdjan): Replace IC call with megamorphic call. 121 // converted to megamorphic calls.
105 return false; 122 return false;
106 } 123 }
124 // Empty IC data.
107 GrowableArray<intptr_t> class_ids(call->ic_data()->num_args_tested()); 125 GrowableArray<intptr_t> class_ids(call->ic_data()->num_args_tested());
108 ASSERT(call->ic_data()->num_args_tested() <= call->ArgumentCount()); 126 ASSERT(call->ic_data()->num_args_tested() <= call->ArgumentCount());
109 for (intptr_t i = 0; i < call->ic_data()->num_args_tested(); i++) { 127 for (intptr_t i = 0; i < call->ic_data()->num_args_tested(); i++) {
110 intptr_t cid = call->PushArgumentAt(i)->value()->Type()->ToCid(); 128 const intptr_t cid = call->PushArgumentAt(i)->value()->Type()->ToCid();
111 class_ids.Add(cid); 129 class_ids.Add(cid);
112 } 130 }
113 if (class_ids[0] != kDynamicCid) { 131 // We guess that comparison and binary operations typically
132 // have both arguments of the same cid. If only one argument's cid is known,
133 // assume the other argument has the same cid.
134 const Token::Kind op_kind = call->token_kind();
135 if (Token::IsRelationalOperator(op_kind) ||
136 Token::IsEqualityOperator(op_kind) ||
137 Token::IsBinaryOperator(op_kind)) {
138 // If left or right is a number -> make the other a number as well.
139 const intptr_t cid_0 = class_ids[0];
140 const intptr_t cid_1 = class_ids[1];
141 if ((cid_0 == kDynamicCid) && (IsNumberCid(cid_1))) {
142 class_ids[0] = cid_1;
143 } else if (IsNumberCid(cid_0) && (cid_1 == kDynamicCid)) {
144 class_ids[1] = cid_0;
145 }
146 }
147 if (NoneIsDynamic(class_ids)) {
114 ArgumentsDescriptor args_desc( 148 ArgumentsDescriptor args_desc(
115 Array::Handle(ArgumentsDescriptor::New(call->ArgumentCount(), 149 Array::Handle(ArgumentsDescriptor::New(call->ArgumentCount(),
116 call->argument_names()))); 150 call->argument_names())));
117 const Class& receiver_class = Class::Handle( 151 const Class& receiver_class = Class::Handle(
118 Isolate::Current()->class_table()->At(class_ids[0])); 152 Isolate::Current()->class_table()->At(class_ids[0]));
119 const Function& function = Function::Handle( 153 const Function& function = Function::Handle(
120 Resolver::ResolveDynamicForReceiverClass( 154 Resolver::ResolveDynamicForReceiverClass(
121 receiver_class, 155 receiver_class,
122 call->function_name(), 156 call->function_name(),
123 args_desc)); 157 args_desc));
124 if (function.IsNull()) { 158 if (function.IsNull()) {
125 return false; 159 return false;
126 } 160 }
127 // Create new ICData, do not modify the one attached to the instruction 161
128 // since it is attached to the assembly instruction itself.
129 // TODO(srdjan): Prevent modification of ICData object that is
130 // referenced in assembly code.
131 ICData& ic_data = ICData::ZoneHandle(ICData::New( 162 ICData& ic_data = ICData::ZoneHandle(ICData::New(
132 flow_graph_->parsed_function().function(), 163 flow_graph_->parsed_function().function(),
133 call->function_name(), 164 call->function_name(),
134 Object::empty_array(), // Dummy argument descriptor. 165 Object::empty_array(), // Dummy argument descriptor.
135 call->deopt_id(), 166 call->deopt_id(),
136 class_ids.length())); 167 class_ids.length()));
137 if (class_ids.length() > 1) { 168 if (class_ids.length() > 1) {
138 ic_data.AddCheck(class_ids, function); 169 ic_data.AddCheck(class_ids, function);
139 } else { 170 } else {
140 ASSERT(class_ids.length() == 1); 171 ASSERT(class_ids.length() == 1);
(...skipping 6758 matching lines...) Expand 10 before | Expand all | Expand 10 after
6899 SetValue(instr, non_constant_); 6930 SetValue(instr, non_constant_);
6900 } 6931 }
6901 6932
6902 6933
6903 void ConstantPropagator::VisitUnboxInteger(UnboxIntegerInstr* instr) { 6934 void ConstantPropagator::VisitUnboxInteger(UnboxIntegerInstr* instr) {
6904 // TODO(kmillikin): Handle unbox operation. 6935 // TODO(kmillikin): Handle unbox operation.
6905 SetValue(instr, non_constant_); 6936 SetValue(instr, non_constant_);
6906 } 6937 }
6907 6938
6908 6939
6909 void ConstantPropagator::VisitBinaryMintOp( 6940 void ConstantPropagator::VisitBinaryMintOp(BinaryMintOpInstr* instr) {
6910 BinaryMintOpInstr* instr) {
6911 HandleBinaryOp(instr, instr->op_kind(), *instr->left(), *instr->right()); 6941 HandleBinaryOp(instr, instr->op_kind(), *instr->left(), *instr->right());
6912 } 6942 }
6913 6943
6914 6944
6915 void ConstantPropagator::VisitShiftMintOp( 6945 void ConstantPropagator::VisitShiftMintOp(ShiftMintOpInstr* instr) {
6916 ShiftMintOpInstr* instr) {
6917 HandleBinaryOp(instr, instr->op_kind(), *instr->left(), *instr->right()); 6946 HandleBinaryOp(instr, instr->op_kind(), *instr->left(), *instr->right());
6918 } 6947 }
6919 6948
6920 6949
6921 void ConstantPropagator::VisitUnaryMintOp( 6950 void ConstantPropagator::VisitUnaryMintOp(UnaryMintOpInstr* instr) {
6922 UnaryMintOpInstr* instr) {
6923 // TODO(kmillikin): Handle unary operations. 6951 // TODO(kmillikin): Handle unary operations.
6924 SetValue(instr, non_constant_); 6952 SetValue(instr, non_constant_);
6925 } 6953 }
6926 6954
6927 6955
6928 void ConstantPropagator::VisitUnarySmiOp(UnarySmiOpInstr* instr) { 6956 void ConstantPropagator::VisitUnarySmiOp(UnarySmiOpInstr* instr) {
6929 const Object& value = instr->value()->definition()->constant_value(); 6957 const Object& value = instr->value()->definition()->constant_value();
6930 if (IsNonConstant(value)) { 6958 if (IsNonConstant(value)) {
6931 SetValue(instr, non_constant_); 6959 SetValue(instr, non_constant_);
6932 } else if (IsConstant(value)) { 6960 } else if (IsConstant(value)) {
(...skipping 1113 matching lines...) Expand 10 before | Expand all | Expand 10 after
8046 } 8074 }
8047 8075
8048 // Insert materializations at environment uses. 8076 // Insert materializations at environment uses.
8049 for (intptr_t i = 0; i < exits.length(); i++) { 8077 for (intptr_t i = 0; i < exits.length(); i++) {
8050 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); 8078 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields);
8051 } 8079 }
8052 } 8080 }
8053 8081
8054 8082
8055 } // namespace dart 8083 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698