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

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

Issue 1533383003: Remove instantiator argument in generated code for type tests. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: fix typo Created 5 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
« no previous file with comments | « runtime/vm/flow_graph_compiler_x64.cc ('k') | runtime/vm/il_printer.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/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/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/cpu.h" 10 #include "vm/cpu.h"
(...skipping 1285 matching lines...) Expand 10 before | Expand all | Expand 10 after
1296 *entry = new(Z) TargetEntryInstr(flow_graph()->allocate_block_id(), 1296 *entry = new(Z) TargetEntryInstr(flow_graph()->allocate_block_id(),
1297 call->GetBlock()->try_index()); 1297 call->GetBlock()->try_index());
1298 (*entry)->InheritDeoptTarget(Z, call); 1298 (*entry)->InheritDeoptTarget(Z, call);
1299 Instruction* cursor = *entry; 1299 Instruction* cursor = *entry;
1300 if (I->flags().type_checks()) { 1300 if (I->flags().type_checks()) {
1301 // Only type check for the value. A type check for the index is not 1301 // Only type check for the value. A type check for the index is not
1302 // needed here because we insert a deoptimizing smi-check for the case 1302 // needed here because we insert a deoptimizing smi-check for the case
1303 // the index is not a smi. 1303 // the index is not a smi.
1304 const AbstractType& value_type = 1304 const AbstractType& value_type =
1305 AbstractType::ZoneHandle(Z, target.ParameterTypeAt(2)); 1305 AbstractType::ZoneHandle(Z, target.ParameterTypeAt(2));
1306 Definition* instantiator = NULL;
1307 Definition* type_args = NULL; 1306 Definition* type_args = NULL;
1308 switch (array_cid) { 1307 switch (array_cid) {
1309 case kArrayCid: 1308 case kArrayCid:
1310 case kGrowableObjectArrayCid: { 1309 case kGrowableObjectArrayCid: {
1311 const Class& instantiator_class = Class::Handle(Z, target.Owner()); 1310 const Class& instantiator_class = Class::Handle(Z, target.Owner());
1312 intptr_t type_arguments_field_offset = 1311 intptr_t type_arguments_field_offset =
1313 instantiator_class.type_arguments_field_offset(); 1312 instantiator_class.type_arguments_field_offset();
1314 LoadFieldInstr* load_type_args = 1313 LoadFieldInstr* load_type_args =
1315 new(Z) LoadFieldInstr(new(Z) Value(array), 1314 new(Z) LoadFieldInstr(new(Z) Value(array),
1316 type_arguments_field_offset, 1315 type_arguments_field_offset,
1317 Type::ZoneHandle(Z), // No type. 1316 Type::ZoneHandle(Z), // No type.
1318 call->token_pos()); 1317 call->token_pos());
1319 cursor = flow_graph()->AppendTo(cursor, 1318 cursor = flow_graph()->AppendTo(cursor,
1320 load_type_args, 1319 load_type_args,
1321 NULL, 1320 NULL,
1322 FlowGraph::kValue); 1321 FlowGraph::kValue);
1323 1322
1324 instantiator = array;
1325 type_args = load_type_args; 1323 type_args = load_type_args;
1326 break; 1324 break;
1327 } 1325 }
1328 case kTypedDataInt8ArrayCid: 1326 case kTypedDataInt8ArrayCid:
1329 case kTypedDataUint8ArrayCid: 1327 case kTypedDataUint8ArrayCid:
1330 case kTypedDataUint8ClampedArrayCid: 1328 case kTypedDataUint8ClampedArrayCid:
1331 case kExternalTypedDataUint8ArrayCid: 1329 case kExternalTypedDataUint8ArrayCid:
1332 case kExternalTypedDataUint8ClampedArrayCid: 1330 case kExternalTypedDataUint8ClampedArrayCid:
1333 case kTypedDataInt16ArrayCid: 1331 case kTypedDataInt16ArrayCid:
1334 case kTypedDataUint16ArrayCid: 1332 case kTypedDataUint16ArrayCid:
1335 case kTypedDataInt32ArrayCid: 1333 case kTypedDataInt32ArrayCid:
1336 case kTypedDataUint32ArrayCid: 1334 case kTypedDataUint32ArrayCid:
1337 case kTypedDataInt64ArrayCid: 1335 case kTypedDataInt64ArrayCid:
1338 ASSERT(value_type.IsIntType()); 1336 ASSERT(value_type.IsIntType());
1339 // Fall through. 1337 // Fall through.
1340 case kTypedDataFloat32ArrayCid: 1338 case kTypedDataFloat32ArrayCid:
1341 case kTypedDataFloat64ArrayCid: { 1339 case kTypedDataFloat64ArrayCid: {
1342 type_args = instantiator = flow_graph_->constant_null(); 1340 type_args = flow_graph_->constant_null();
1343 ASSERT((array_cid != kTypedDataFloat32ArrayCid && 1341 ASSERT((array_cid != kTypedDataFloat32ArrayCid &&
1344 array_cid != kTypedDataFloat64ArrayCid) || 1342 array_cid != kTypedDataFloat64ArrayCid) ||
1345 value_type.IsDoubleType()); 1343 value_type.IsDoubleType());
1346 ASSERT(value_type.IsInstantiated()); 1344 ASSERT(value_type.IsInstantiated());
1347 break; 1345 break;
1348 } 1346 }
1349 case kTypedDataFloat32x4ArrayCid: { 1347 case kTypedDataFloat32x4ArrayCid: {
1350 type_args = instantiator = flow_graph_->constant_null(); 1348 type_args = flow_graph_->constant_null();
1351 ASSERT((array_cid != kTypedDataFloat32x4ArrayCid) || 1349 ASSERT((array_cid != kTypedDataFloat32x4ArrayCid) ||
1352 value_type.IsFloat32x4Type()); 1350 value_type.IsFloat32x4Type());
1353 ASSERT(value_type.IsInstantiated()); 1351 ASSERT(value_type.IsInstantiated());
1354 break; 1352 break;
1355 } 1353 }
1356 case kTypedDataFloat64x2ArrayCid: { 1354 case kTypedDataFloat64x2ArrayCid: {
1357 type_args = instantiator = flow_graph_->constant_null(); 1355 type_args = flow_graph_->constant_null();
1358 ASSERT((array_cid != kTypedDataFloat64x2ArrayCid) || 1356 ASSERT((array_cid != kTypedDataFloat64x2ArrayCid) ||
1359 value_type.IsFloat64x2Type()); 1357 value_type.IsFloat64x2Type());
1360 ASSERT(value_type.IsInstantiated()); 1358 ASSERT(value_type.IsInstantiated());
1361 break; 1359 break;
1362 } 1360 }
1363 default: 1361 default:
1364 // TODO(fschneider): Add support for other array types. 1362 // TODO(fschneider): Add support for other array types.
1365 UNREACHABLE(); 1363 UNREACHABLE();
1366 } 1364 }
1367 AssertAssignableInstr* assert_value = 1365 AssertAssignableInstr* assert_value =
1368 new(Z) AssertAssignableInstr(token_pos, 1366 new(Z) AssertAssignableInstr(token_pos,
1369 new(Z) Value(stored_value), 1367 new(Z) Value(stored_value),
1370 new(Z) Value(instantiator),
1371 new(Z) Value(type_args), 1368 new(Z) Value(type_args),
1372 value_type, 1369 value_type,
1373 Symbols::Value(), 1370 Symbols::Value(),
1374 call->deopt_id()); 1371 call->deopt_id());
1375 cursor = flow_graph()->AppendTo(cursor, 1372 cursor = flow_graph()->AppendTo(cursor,
1376 assert_value, 1373 assert_value,
1377 call->env(), 1374 call->env(),
1378 FlowGraph::kValue); 1375 FlowGraph::kValue);
1379 } 1376 }
1380 1377
(...skipping 2663 matching lines...) Expand 10 before | Expand all | Expand 10 after
4044 } 4041 }
4045 4042
4046 return true; // May deoptimize since we have not identified all 'true' tests. 4043 return true; // May deoptimize since we have not identified all 'true' tests.
4047 } 4044 }
4048 4045
4049 4046
4050 // TODO(srdjan): Use ICData to check if always true or false. 4047 // TODO(srdjan): Use ICData to check if always true or false.
4051 void FlowGraphOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) { 4048 void FlowGraphOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) {
4052 ASSERT(Token::IsTypeTestOperator(call->token_kind())); 4049 ASSERT(Token::IsTypeTestOperator(call->token_kind()));
4053 Definition* left = call->ArgumentAt(0); 4050 Definition* left = call->ArgumentAt(0);
4054 Definition* instantiator = NULL;
4055 Definition* type_args = NULL; 4051 Definition* type_args = NULL;
4056 AbstractType& type = AbstractType::ZoneHandle(Z); 4052 AbstractType& type = AbstractType::ZoneHandle(Z);
4057 bool negate = false; 4053 bool negate = false;
4058 if (call->ArgumentCount() == 2) { 4054 if (call->ArgumentCount() == 2) {
4059 instantiator = flow_graph()->constant_null();
4060 type_args = flow_graph()->constant_null(); 4055 type_args = flow_graph()->constant_null();
4061 if (call->function_name().raw() == 4056 if (call->function_name().raw() ==
4062 Library::PrivateCoreLibName(Symbols::_instanceOfNum()).raw()) { 4057 Library::PrivateCoreLibName(Symbols::_instanceOfNum()).raw()) {
4063 type = Type::Number(); 4058 type = Type::Number();
4064 } else if (call->function_name().raw() == 4059 } else if (call->function_name().raw() ==
4065 Library::PrivateCoreLibName(Symbols::_instanceOfInt()).raw()) { 4060 Library::PrivateCoreLibName(Symbols::_instanceOfInt()).raw()) {
4066 type = Type::IntType(); 4061 type = Type::IntType();
4067 } else if (call->function_name().raw() == 4062 } else if (call->function_name().raw() ==
4068 Library::PrivateCoreLibName(Symbols::_instanceOfSmi()).raw()) { 4063 Library::PrivateCoreLibName(Symbols::_instanceOfSmi()).raw()) {
4069 type = Type::SmiType(); 4064 type = Type::SmiType();
4070 } else if (call->function_name().raw() == 4065 } else if (call->function_name().raw() ==
4071 Library::PrivateCoreLibName(Symbols::_instanceOfDouble()).raw()) { 4066 Library::PrivateCoreLibName(Symbols::_instanceOfDouble()).raw()) {
4072 type = Type::Double(); 4067 type = Type::Double();
4073 } else if (call->function_name().raw() == 4068 } else if (call->function_name().raw() ==
4074 Library::PrivateCoreLibName(Symbols::_instanceOfString()).raw()) { 4069 Library::PrivateCoreLibName(Symbols::_instanceOfString()).raw()) {
4075 type = Type::StringType(); 4070 type = Type::StringType();
4076 } else { 4071 } else {
4077 UNIMPLEMENTED(); 4072 UNIMPLEMENTED();
4078 } 4073 }
4079 negate = Bool::Cast(call->ArgumentAt(1)->OriginalDefinition() 4074 negate = Bool::Cast(call->ArgumentAt(1)->OriginalDefinition()
4080 ->AsConstant()->value()).value(); 4075 ->AsConstant()->value()).value();
4081 } else { 4076 } else {
4082 instantiator = call->ArgumentAt(1); 4077 type_args = call->ArgumentAt(1);
4083 type_args = call->ArgumentAt(2); 4078 type = AbstractType::Cast(call->ArgumentAt(2)->AsConstant()->value()).raw();
4084 type = AbstractType::Cast(call->ArgumentAt(3)->AsConstant()->value()).raw(); 4079 negate = Bool::Cast(call->ArgumentAt(3)->OriginalDefinition()
4085 negate = Bool::Cast(call->ArgumentAt(4)->OriginalDefinition()
4086 ->AsConstant()->value()).value(); 4080 ->AsConstant()->value()).value();
4087 } 4081 }
4088 const ICData& unary_checks = 4082 const ICData& unary_checks =
4089 ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecks()); 4083 ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecks());
4090 if (FLAG_warn_on_javascript_compatibility && 4084 if (FLAG_warn_on_javascript_compatibility &&
4091 !unary_checks.IssuedJSWarning() && 4085 !unary_checks.IssuedJSWarning() &&
4092 (type.IsIntType() || type.IsDoubleType() || !type.IsInstantiated())) { 4086 (type.IsIntType() || type.IsDoubleType() || !type.IsInstantiated())) {
4093 // No warning was reported yet for this type check, either because it has 4087 // No warning was reported yet for this type check, either because it has
4094 // not been executed yet, or because no problematic combinations of instance 4088 // not been executed yet, or because no problematic combinations of instance
4095 // type and test type have been encountered so far. A warning may still be 4089 // type and test type have been encountered so far. A warning may still be
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
4152 new(Z) Value(left_cid), 4146 new(Z) Value(left_cid),
4153 new(Z) Value(cid), 4147 new(Z) Value(cid),
4154 false); // No number check. 4148 false); // No number check.
4155 ReplaceCall(call, check_cid); 4149 ReplaceCall(call, check_cid);
4156 return; 4150 return;
4157 } 4151 }
4158 4152
4159 InstanceOfInstr* instance_of = 4153 InstanceOfInstr* instance_of =
4160 new(Z) InstanceOfInstr(call->token_pos(), 4154 new(Z) InstanceOfInstr(call->token_pos(),
4161 new(Z) Value(left), 4155 new(Z) Value(left),
4162 new(Z) Value(instantiator),
4163 new(Z) Value(type_args), 4156 new(Z) Value(type_args),
4164 type, 4157 type,
4165 negate, 4158 negate,
4166 call->deopt_id()); 4159 call->deopt_id());
4167 ReplaceCall(call, instance_of); 4160 ReplaceCall(call, instance_of);
4168 } 4161 }
4169 4162
4170 4163
4171 // TODO(srdjan): Apply optimizations as in ReplaceWithInstanceOf (TestCids). 4164 // TODO(srdjan): Apply optimizations as in ReplaceWithInstanceOf (TestCids).
4172 void FlowGraphOptimizer::ReplaceWithTypeCast(InstanceCallInstr* call) { 4165 void FlowGraphOptimizer::ReplaceWithTypeCast(InstanceCallInstr* call) {
4173 ASSERT(Token::IsTypeCastOperator(call->token_kind())); 4166 ASSERT(Token::IsTypeCastOperator(call->token_kind()));
4174 Definition* left = call->ArgumentAt(0); 4167 Definition* left = call->ArgumentAt(0);
4175 Definition* instantiator = call->ArgumentAt(1); 4168 Definition* type_args = call->ArgumentAt(1);
4176 Definition* type_args = call->ArgumentAt(2);
4177 const AbstractType& type = 4169 const AbstractType& type =
4178 AbstractType::Cast(call->ArgumentAt(3)->AsConstant()->value()); 4170 AbstractType::Cast(call->ArgumentAt(2)->AsConstant()->value());
4179 ASSERT(!type.IsMalformedOrMalbounded()); 4171 ASSERT(!type.IsMalformedOrMalbounded());
4180 const ICData& unary_checks = 4172 const ICData& unary_checks =
4181 ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecks()); 4173 ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecks());
4182 if (FLAG_warn_on_javascript_compatibility && 4174 if (FLAG_warn_on_javascript_compatibility &&
4183 !unary_checks.IssuedJSWarning() && 4175 !unary_checks.IssuedJSWarning() &&
4184 (type.IsIntType() || type.IsDoubleType() || !type.IsInstantiated())) { 4176 (type.IsIntType() || type.IsDoubleType() || !type.IsInstantiated())) {
4185 // No warning was reported yet for this type check, either because it has 4177 // No warning was reported yet for this type check, either because it has
4186 // not been executed yet, or because no problematic combinations of instance 4178 // not been executed yet, or because no problematic combinations of instance
4187 // type and test type have been encountered so far. A warning may still be 4179 // type and test type have been encountered so far. A warning may still be
4188 // reported, so do not replace the instance call. 4180 // reported, so do not replace the instance call.
(...skipping 18 matching lines...) Expand all
4207 ASSERT(current_iterator()->Current() == call); 4199 ASSERT(current_iterator()->Current() == call);
4208 current_iterator()->RemoveCurrentFromGraph(); 4200 current_iterator()->RemoveCurrentFromGraph();
4209 return; 4201 return;
4210 } 4202 }
4211 } 4203 }
4212 const String& dst_name = String::ZoneHandle(Z, 4204 const String& dst_name = String::ZoneHandle(Z,
4213 Symbols::New(Exceptions::kCastErrorDstName)); 4205 Symbols::New(Exceptions::kCastErrorDstName));
4214 AssertAssignableInstr* assert_as = 4206 AssertAssignableInstr* assert_as =
4215 new(Z) AssertAssignableInstr(call->token_pos(), 4207 new(Z) AssertAssignableInstr(call->token_pos(),
4216 new(Z) Value(left), 4208 new(Z) Value(left),
4217 new(Z) Value(instantiator),
4218 new(Z) Value(type_args), 4209 new(Z) Value(type_args),
4219 type, 4210 type,
4220 dst_name, 4211 dst_name,
4221 call->deopt_id()); 4212 call->deopt_id());
4222 ReplaceCall(call, assert_as); 4213 ReplaceCall(call, assert_as);
4223 } 4214 }
4224 4215
4225 4216
4226 bool FlowGraphOptimizer::IsBlackListedForInlining(intptr_t call_deopt_id) { 4217 bool FlowGraphOptimizer::IsBlackListedForInlining(intptr_t call_deopt_id) {
4227 for (intptr_t i = 0; i < inlining_black_list_->length(); ++i) { 4218 for (intptr_t i = 0; i < inlining_black_list_->length(); ++i) {
(...skipping 4626 matching lines...) Expand 10 before | Expand all | Expand 10 after
8854 8845
8855 // Insert materializations at environment uses. 8846 // Insert materializations at environment uses.
8856 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { 8847 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) {
8857 CreateMaterializationAt( 8848 CreateMaterializationAt(
8858 exits_collector_.exits()[i], alloc, *slots); 8849 exits_collector_.exits()[i], alloc, *slots);
8859 } 8850 }
8860 } 8851 }
8861 8852
8862 8853
8863 } // namespace dart 8854 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_x64.cc ('k') | runtime/vm/il_printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698