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

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

Issue 290993003: VM: Remove unnecessary field use_kind from IL instructions. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 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 | 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/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 const intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(cid); 314 const intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(cid);
315 ConstantInstr* index_instr = 315 ConstantInstr* index_instr =
316 flow_graph()->GetConstant(Smi::Handle(Smi::New(ix))); 316 flow_graph()->GetConstant(Smi::Handle(Smi::New(ix)));
317 LoadIndexedInstr* load = new LoadIndexedInstr(new Value(instr), 317 LoadIndexedInstr* load = new LoadIndexedInstr(new Value(instr),
318 new Value(index_instr), 318 new Value(index_instr),
319 index_scale, 319 index_scale,
320 cid, 320 cid,
321 Isolate::kNoDeoptId, 321 Isolate::kNoDeoptId,
322 instr->token_pos()); 322 instr->token_pos());
323 instr->ReplaceUsesWith(load); 323 instr->ReplaceUsesWith(load);
324 flow_graph()->InsertAfter(instr, load, NULL, Definition::kValue); 324 flow_graph()->InsertAfter(instr, load, NULL, FlowGraph::kValue);
325 } 325 }
326 326
327 327
328 void FlowGraphOptimizer::AppendExtractNthOutputForMerged(Definition* instr, 328 void FlowGraphOptimizer::AppendExtractNthOutputForMerged(Definition* instr,
329 intptr_t index, 329 intptr_t index,
330 Representation rep, 330 Representation rep,
331 intptr_t cid) { 331 intptr_t cid) {
332 ExtractNthOutputInstr* extract = new ExtractNthOutputInstr(new Value(instr), 332 ExtractNthOutputInstr* extract = new ExtractNthOutputInstr(new Value(instr),
333 index, 333 index,
334 rep, 334 rep,
335 cid); 335 cid);
336 instr->ReplaceUsesWith(extract); 336 instr->ReplaceUsesWith(extract);
337 flow_graph()->InsertAfter(instr, extract, NULL, Definition::kValue); 337 flow_graph()->InsertAfter(instr, extract, NULL, FlowGraph::kValue);
338 } 338 }
339 339
340 340
341 // Dart: 341 // Dart:
342 // var x = d % 10; 342 // var x = d % 10;
343 // var y = d ~/ 10; 343 // var y = d ~/ 10;
344 // var z = x + y; 344 // var z = x + y;
345 // 345 //
346 // IL: 346 // IL:
347 // v4 <- %(v2, v3) 347 // v4 <- %(v2, v3)
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 609
610 } else if ((from == kUnboxedMint) && (to == kTagged)) { 610 } else if ((from == kUnboxedMint) && (to == kTagged)) {
611 converted = new BoxIntegerInstr(use->CopyWithType()); 611 converted = new BoxIntegerInstr(use->CopyWithType());
612 612
613 } else if (from == kUnboxedMint && to == kUnboxedDouble) { 613 } else if (from == kUnboxedMint && to == kUnboxedDouble) {
614 ASSERT(CanUnboxDouble()); 614 ASSERT(CanUnboxDouble());
615 // Convert by boxing/unboxing. 615 // Convert by boxing/unboxing.
616 // TODO(fschneider): Implement direct unboxed mint-to-double conversion. 616 // TODO(fschneider): Implement direct unboxed mint-to-double conversion.
617 BoxIntegerInstr* boxed = new BoxIntegerInstr(use->CopyWithType()); 617 BoxIntegerInstr* boxed = new BoxIntegerInstr(use->CopyWithType());
618 use->BindTo(boxed); 618 use->BindTo(boxed);
619 InsertBefore(insert_before, boxed, NULL, Definition::kValue); 619 InsertBefore(insert_before, boxed, NULL, FlowGraph::kValue);
620 620
621 const intptr_t deopt_id = (deopt_target != NULL) ? 621 const intptr_t deopt_id = (deopt_target != NULL) ?
622 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; 622 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
623 converted = new UnboxDoubleInstr(new Value(boxed), deopt_id); 623 converted = new UnboxDoubleInstr(new Value(boxed), deopt_id);
624 624
625 } else if ((from == kUnboxedDouble) && (to == kTagged)) { 625 } else if ((from == kUnboxedDouble) && (to == kTagged)) {
626 ASSERT(CanUnboxDouble()); 626 ASSERT(CanUnboxDouble());
627 converted = new BoxDoubleInstr(use->CopyWithType()); 627 converted = new BoxDoubleInstr(use->CopyWithType());
628 628
629 } else if ((from == kTagged) && (to == kUnboxedDouble)) { 629 } else if ((from == kTagged) && (to == kUnboxedDouble)) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
681 } else if (from == kUnboxedFloat32x4) { 681 } else if (from == kUnboxedFloat32x4) {
682 boxed = new BoxFloat32x4Instr(use->CopyWithType()); 682 boxed = new BoxFloat32x4Instr(use->CopyWithType());
683 } else if (from == kUnboxedMint) { 683 } else if (from == kUnboxedMint) {
684 boxed = new BoxIntegerInstr(use->CopyWithType()); 684 boxed = new BoxIntegerInstr(use->CopyWithType());
685 } else if (from == kUnboxedFloat64x2) { 685 } else if (from == kUnboxedFloat64x2) {
686 boxed = new BoxFloat64x2Instr(use->CopyWithType()); 686 boxed = new BoxFloat64x2Instr(use->CopyWithType());
687 } else { 687 } else {
688 UNIMPLEMENTED(); 688 UNIMPLEMENTED();
689 } 689 }
690 use->BindTo(boxed); 690 use->BindTo(boxed);
691 InsertBefore(insert_before, boxed, NULL, Definition::kValue); 691 InsertBefore(insert_before, boxed, NULL, FlowGraph::kValue);
692 Value* to_value = new Value(boxed); 692 Value* to_value = new Value(boxed);
693 if (to == kUnboxedDouble) { 693 if (to == kUnboxedDouble) {
694 converted = new UnboxDoubleInstr(to_value, deopt_id); 694 converted = new UnboxDoubleInstr(to_value, deopt_id);
695 } else if (to == kUnboxedInt32x4) { 695 } else if (to == kUnboxedInt32x4) {
696 converted = new UnboxInt32x4Instr(to_value, deopt_id); 696 converted = new UnboxInt32x4Instr(to_value, deopt_id);
697 } else if (to == kUnboxedFloat32x4) { 697 } else if (to == kUnboxedFloat32x4) {
698 converted = new UnboxFloat32x4Instr(to_value, deopt_id); 698 converted = new UnboxFloat32x4Instr(to_value, deopt_id);
699 } else if (to == kUnboxedMint) { 699 } else if (to == kUnboxedMint) {
700 converted = new UnboxIntegerInstr(to_value, deopt_id); 700 converted = new UnboxIntegerInstr(to_value, deopt_id);
701 } else if (to == kUnboxedFloat64x2) { 701 } else if (to == kUnboxedFloat64x2) {
702 converted = new UnboxFloat64x2Instr(to_value, deopt_id); 702 converted = new UnboxFloat64x2Instr(to_value, deopt_id);
703 } else { 703 } else {
704 UNIMPLEMENTED(); 704 UNIMPLEMENTED();
705 } 705 }
706 } 706 }
707 ASSERT(converted != NULL); 707 ASSERT(converted != NULL);
708 InsertBefore(insert_before, converted, use->instruction()->env(), 708 InsertBefore(insert_before, converted, use->instruction()->env(),
709 Definition::kValue); 709 FlowGraph::kValue);
710 if (is_environment_use) { 710 if (is_environment_use) {
711 use->BindToEnvironment(converted); 711 use->BindToEnvironment(converted);
712 } else { 712 } else {
713 use->BindTo(converted); 713 use->BindTo(converted);
714 } 714 }
715 } 715 }
716 716
717 717
718 void FlowGraphOptimizer::ConvertUse(Value* use, Representation from_rep) { 718 void FlowGraphOptimizer::ConvertUse(Value* use, Representation from_rep) {
719 const Representation to_rep = 719 const Representation to_rep =
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
977 void FlowGraphOptimizer::AddCheckSmi(Definition* to_check, 977 void FlowGraphOptimizer::AddCheckSmi(Definition* to_check,
978 intptr_t deopt_id, 978 intptr_t deopt_id,
979 Environment* deopt_environment, 979 Environment* deopt_environment,
980 Instruction* insert_before) { 980 Instruction* insert_before) {
981 if (to_check->Type()->ToCid() != kSmiCid) { 981 if (to_check->Type()->ToCid() != kSmiCid) {
982 InsertBefore(insert_before, 982 InsertBefore(insert_before,
983 new CheckSmiInstr(new Value(to_check), 983 new CheckSmiInstr(new Value(to_check),
984 deopt_id, 984 deopt_id,
985 insert_before->token_pos()), 985 insert_before->token_pos()),
986 deopt_environment, 986 deopt_environment,
987 Definition::kEffect); 987 FlowGraph::kEffect);
988 } 988 }
989 } 989 }
990 990
991 991
992 Instruction* FlowGraphOptimizer::GetCheckClass(Definition* to_check, 992 Instruction* FlowGraphOptimizer::GetCheckClass(Definition* to_check,
993 const ICData& unary_checks, 993 const ICData& unary_checks,
994 intptr_t deopt_id, 994 intptr_t deopt_id,
995 intptr_t token_pos) { 995 intptr_t token_pos) {
996 if ((unary_checks.NumberOfChecks() == 1) && 996 if ((unary_checks.NumberOfChecks() == 1) &&
997 (unary_checks.GetReceiverClassIdAt(0) == kSmiCid)) { 997 (unary_checks.GetReceiverClassIdAt(0) == kSmiCid)) {
998 return new CheckSmiInstr(new Value(to_check), 998 return new CheckSmiInstr(new Value(to_check),
999 deopt_id, 999 deopt_id,
1000 token_pos); 1000 token_pos);
1001 } 1001 }
1002 return new CheckClassInstr( 1002 return new CheckClassInstr(
1003 new Value(to_check), deopt_id, unary_checks, token_pos); 1003 new Value(to_check), deopt_id, unary_checks, token_pos);
1004 } 1004 }
1005 1005
1006 1006
1007 void FlowGraphOptimizer::AddCheckClass(Definition* to_check, 1007 void FlowGraphOptimizer::AddCheckClass(Definition* to_check,
1008 const ICData& unary_checks, 1008 const ICData& unary_checks,
1009 intptr_t deopt_id, 1009 intptr_t deopt_id,
1010 Environment* deopt_environment, 1010 Environment* deopt_environment,
1011 Instruction* insert_before) { 1011 Instruction* insert_before) {
1012 // Type propagation has not run yet, we cannot eliminate the check. 1012 // Type propagation has not run yet, we cannot eliminate the check.
1013 Instruction* check = GetCheckClass( 1013 Instruction* check = GetCheckClass(
1014 to_check, unary_checks, deopt_id, insert_before->token_pos()); 1014 to_check, unary_checks, deopt_id, insert_before->token_pos());
1015 InsertBefore(insert_before, check, deopt_environment, Definition::kEffect); 1015 InsertBefore(insert_before, check, deopt_environment, FlowGraph::kEffect);
1016 } 1016 }
1017 1017
1018 1018
1019 void FlowGraphOptimizer::AddReceiverCheck(InstanceCallInstr* call) { 1019 void FlowGraphOptimizer::AddReceiverCheck(InstanceCallInstr* call) {
1020 AddCheckClass(call->ArgumentAt(0), 1020 AddCheckClass(call->ArgumentAt(0),
1021 ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecks()), 1021 ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecks()),
1022 call->deopt_id(), 1022 call->deopt_id(),
1023 call->env(), 1023 call->env(),
1024 call); 1024 call);
1025 } 1025 }
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
1200 intptr_t type_arguments_field_offset = 1200 intptr_t type_arguments_field_offset =
1201 instantiator_class.type_arguments_field_offset(); 1201 instantiator_class.type_arguments_field_offset();
1202 LoadFieldInstr* load_type_args = 1202 LoadFieldInstr* load_type_args =
1203 new LoadFieldInstr(new Value(array), 1203 new LoadFieldInstr(new Value(array),
1204 type_arguments_field_offset, 1204 type_arguments_field_offset,
1205 Type::ZoneHandle(), // No type. 1205 Type::ZoneHandle(), // No type.
1206 call->token_pos()); 1206 call->token_pos());
1207 cursor = flow_graph()->AppendTo(cursor, 1207 cursor = flow_graph()->AppendTo(cursor,
1208 load_type_args, 1208 load_type_args,
1209 NULL, 1209 NULL,
1210 Definition::kValue); 1210 FlowGraph::kValue);
1211 1211
1212 instantiator = array; 1212 instantiator = array;
1213 type_args = load_type_args; 1213 type_args = load_type_args;
1214 break; 1214 break;
1215 } 1215 }
1216 case kTypedDataInt8ArrayCid: 1216 case kTypedDataInt8ArrayCid:
1217 case kTypedDataUint8ArrayCid: 1217 case kTypedDataUint8ArrayCid:
1218 case kTypedDataUint8ClampedArrayCid: 1218 case kTypedDataUint8ClampedArrayCid:
1219 case kExternalTypedDataUint8ArrayCid: 1219 case kExternalTypedDataUint8ArrayCid:
1220 case kExternalTypedDataUint8ClampedArrayCid: 1220 case kExternalTypedDataUint8ClampedArrayCid:
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1258 new Value(type_args), 1258 new Value(type_args),
1259 value_type, 1259 value_type,
1260 Symbols::Value()); 1260 Symbols::Value());
1261 // Newly inserted instructions that can deoptimize or throw an exception 1261 // Newly inserted instructions that can deoptimize or throw an exception
1262 // must have a deoptimization id that is valid for lookup in the unoptimized 1262 // must have a deoptimization id that is valid for lookup in the unoptimized
1263 // code. 1263 // code.
1264 assert_value->deopt_id_ = call->deopt_id(); 1264 assert_value->deopt_id_ = call->deopt_id();
1265 cursor = flow_graph()->AppendTo(cursor, 1265 cursor = flow_graph()->AppendTo(cursor,
1266 assert_value, 1266 assert_value,
1267 call->env(), 1267 call->env(),
1268 Definition::kValue); 1268 FlowGraph::kValue);
1269 } 1269 }
1270 1270
1271 array_cid = PrepareInlineIndexedOp(call, 1271 array_cid = PrepareInlineIndexedOp(call,
1272 array_cid, 1272 array_cid,
1273 &array, 1273 &array,
1274 index, 1274 index,
1275 &cursor); 1275 &cursor);
1276 1276
1277 // Check if store barrier is needed. Byte arrays don't need a store barrier. 1277 // Check if store barrier is needed. Byte arrays don't need a store barrier.
1278 StoreBarrierType needs_store_barrier = 1278 StoreBarrierType needs_store_barrier =
1279 (RawObject::IsTypedDataClassId(array_cid) || 1279 (RawObject::IsTypedDataClassId(array_cid) ||
1280 RawObject::IsTypedDataViewClassId(array_cid) || 1280 RawObject::IsTypedDataViewClassId(array_cid) ||
1281 RawObject::IsExternalTypedDataClassId(array_cid)) ? kNoStoreBarrier 1281 RawObject::IsExternalTypedDataClassId(array_cid)) ? kNoStoreBarrier
1282 : kEmitStoreBarrier; 1282 : kEmitStoreBarrier;
1283 if (!value_check.IsNull()) { 1283 if (!value_check.IsNull()) {
1284 // No store barrier needed because checked value is a smi, an unboxed mint, 1284 // No store barrier needed because checked value is a smi, an unboxed mint,
1285 // an unboxed double, an unboxed Float32x4, or unboxed Int32x4. 1285 // an unboxed double, an unboxed Float32x4, or unboxed Int32x4.
1286 needs_store_barrier = kNoStoreBarrier; 1286 needs_store_barrier = kNoStoreBarrier;
1287 Instruction* check = GetCheckClass( 1287 Instruction* check = GetCheckClass(
1288 stored_value, value_check, call->deopt_id(), call->token_pos()); 1288 stored_value, value_check, call->deopt_id(), call->token_pos());
1289 cursor = flow_graph()->AppendTo(cursor, 1289 cursor = flow_graph()->AppendTo(cursor,
1290 check, 1290 check,
1291 call->env(), 1291 call->env(),
1292 Definition::kEffect); 1292 FlowGraph::kEffect);
1293 } 1293 }
1294 1294
1295 if (array_cid == kTypedDataFloat32ArrayCid) { 1295 if (array_cid == kTypedDataFloat32ArrayCid) {
1296 stored_value = 1296 stored_value =
1297 new DoubleToFloatInstr(new Value(stored_value), call->deopt_id()); 1297 new DoubleToFloatInstr(new Value(stored_value), call->deopt_id());
1298 cursor = flow_graph()->AppendTo(cursor, 1298 cursor = flow_graph()->AppendTo(cursor,
1299 stored_value, 1299 stored_value,
1300 NULL, 1300 NULL,
1301 Definition::kValue); 1301 FlowGraph::kValue);
1302 } 1302 }
1303 1303
1304 intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(array_cid); 1304 intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(array_cid);
1305 *last = new StoreIndexedInstr(new Value(array), 1305 *last = new StoreIndexedInstr(new Value(array),
1306 new Value(index), 1306 new Value(index),
1307 new Value(stored_value), 1307 new Value(stored_value),
1308 needs_store_barrier, 1308 needs_store_barrier,
1309 index_scale, 1309 index_scale,
1310 array_cid, 1310 array_cid,
1311 call->deopt_id(), 1311 call->deopt_id(),
1312 call->token_pos()); 1312 call->token_pos());
1313 flow_graph()->AppendTo(cursor, 1313 flow_graph()->AppendTo(cursor,
1314 *last, 1314 *last,
1315 call->env(), 1315 call->env(),
1316 Definition::kEffect); 1316 FlowGraph::kEffect);
1317 return true; 1317 return true;
1318 } 1318 }
1319 1319
1320 1320
1321 bool FlowGraphOptimizer::TryInlineRecognizedMethod(intptr_t receiver_cid, 1321 bool FlowGraphOptimizer::TryInlineRecognizedMethod(intptr_t receiver_cid,
1322 const Function& target, 1322 const Function& target,
1323 Instruction* call, 1323 Instruction* call,
1324 Definition* receiver, 1324 Definition* receiver,
1325 intptr_t token_pos, 1325 intptr_t token_pos,
1326 const ICData& ic_data, 1326 const ICData& ic_data,
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
1560 intptr_t array_cid, 1560 intptr_t array_cid,
1561 Definition** array, 1561 Definition** array,
1562 Definition* index, 1562 Definition* index,
1563 Instruction** cursor) { 1563 Instruction** cursor) {
1564 // Insert index smi check. 1564 // Insert index smi check.
1565 *cursor = flow_graph()->AppendTo(*cursor, 1565 *cursor = flow_graph()->AppendTo(*cursor,
1566 new CheckSmiInstr(new Value(index), 1566 new CheckSmiInstr(new Value(index),
1567 call->deopt_id(), 1567 call->deopt_id(),
1568 call->token_pos()), 1568 call->token_pos()),
1569 call->env(), 1569 call->env(),
1570 Definition::kEffect); 1570 FlowGraph::kEffect);
1571 1571
1572 // Insert array length load and bounds check. 1572 // Insert array length load and bounds check.
1573 LoadFieldInstr* length = 1573 LoadFieldInstr* length =
1574 new LoadFieldInstr(new Value(*array), 1574 new LoadFieldInstr(new Value(*array),
1575 CheckArrayBoundInstr::LengthOffsetFor(array_cid), 1575 CheckArrayBoundInstr::LengthOffsetFor(array_cid),
1576 Type::ZoneHandle(Type::SmiType()), 1576 Type::ZoneHandle(Type::SmiType()),
1577 call->token_pos()); 1577 call->token_pos());
1578 length->set_is_immutable( 1578 length->set_is_immutable(
1579 CheckArrayBoundInstr::IsFixedLengthArrayType(array_cid)); 1579 CheckArrayBoundInstr::IsFixedLengthArrayType(array_cid));
1580 length->set_result_cid(kSmiCid); 1580 length->set_result_cid(kSmiCid);
1581 length->set_recognized_kind( 1581 length->set_recognized_kind(
1582 LoadFieldInstr::RecognizedKindFromArrayCid(array_cid)); 1582 LoadFieldInstr::RecognizedKindFromArrayCid(array_cid));
1583 *cursor = flow_graph()->AppendTo(*cursor, 1583 *cursor = flow_graph()->AppendTo(*cursor,
1584 length, 1584 length,
1585 NULL, 1585 NULL,
1586 Definition::kValue); 1586 FlowGraph::kValue);
1587 1587
1588 *cursor = flow_graph()->AppendTo(*cursor, 1588 *cursor = flow_graph()->AppendTo(*cursor,
1589 new CheckArrayBoundInstr( 1589 new CheckArrayBoundInstr(
1590 new Value(length), 1590 new Value(length),
1591 new Value(index), 1591 new Value(index),
1592 call->deopt_id()), 1592 call->deopt_id()),
1593 call->env(), 1593 call->env(),
1594 Definition::kEffect); 1594 FlowGraph::kEffect);
1595 1595
1596 if (array_cid == kGrowableObjectArrayCid) { 1596 if (array_cid == kGrowableObjectArrayCid) {
1597 // Insert data elements load. 1597 // Insert data elements load.
1598 LoadFieldInstr* elements = 1598 LoadFieldInstr* elements =
1599 new LoadFieldInstr(new Value(*array), 1599 new LoadFieldInstr(new Value(*array),
1600 GrowableObjectArray::data_offset(), 1600 GrowableObjectArray::data_offset(),
1601 Type::ZoneHandle(Type::DynamicType()), 1601 Type::ZoneHandle(Type::DynamicType()),
1602 call->token_pos()); 1602 call->token_pos());
1603 elements->set_result_cid(kArrayCid); 1603 elements->set_result_cid(kArrayCid);
1604 *cursor = flow_graph()->AppendTo(*cursor, 1604 *cursor = flow_graph()->AppendTo(*cursor,
1605 elements, 1605 elements,
1606 NULL, 1606 NULL,
1607 Definition::kValue); 1607 FlowGraph::kValue);
1608 // Load from the data from backing store which is a fixed-length array. 1608 // Load from the data from backing store which is a fixed-length array.
1609 *array = elements; 1609 *array = elements;
1610 array_cid = kArrayCid; 1610 array_cid = kArrayCid;
1611 } else if (RawObject::IsExternalTypedDataClassId(array_cid)) { 1611 } else if (RawObject::IsExternalTypedDataClassId(array_cid)) {
1612 LoadUntaggedInstr* elements = 1612 LoadUntaggedInstr* elements =
1613 new LoadUntaggedInstr(new Value(*array), 1613 new LoadUntaggedInstr(new Value(*array),
1614 ExternalTypedData::data_offset()); 1614 ExternalTypedData::data_offset());
1615 *cursor = flow_graph()->AppendTo(*cursor, 1615 *cursor = flow_graph()->AppendTo(*cursor,
1616 elements, 1616 elements,
1617 NULL, 1617 NULL,
1618 Definition::kValue); 1618 FlowGraph::kValue);
1619 *array = elements; 1619 *array = elements;
1620 } 1620 }
1621 return array_cid; 1621 return array_cid;
1622 } 1622 }
1623 1623
1624 bool FlowGraphOptimizer::InlineGetIndexed(MethodRecognizer::Kind kind, 1624 bool FlowGraphOptimizer::InlineGetIndexed(MethodRecognizer::Kind kind,
1625 Instruction* call, 1625 Instruction* call,
1626 Definition* receiver, 1626 Definition* receiver,
1627 const ICData& ic_data, 1627 const ICData& ic_data,
1628 TargetEntryInstr** entry, 1628 TargetEntryInstr** entry,
(...skipping 28 matching lines...) Expand all
1657 *last = new LoadIndexedInstr(new Value(array), 1657 *last = new LoadIndexedInstr(new Value(array),
1658 new Value(index), 1658 new Value(index),
1659 index_scale, 1659 index_scale,
1660 array_cid, 1660 array_cid,
1661 deopt_id, 1661 deopt_id,
1662 call->token_pos()); 1662 call->token_pos());
1663 cursor = flow_graph()->AppendTo( 1663 cursor = flow_graph()->AppendTo(
1664 cursor, 1664 cursor,
1665 *last, 1665 *last,
1666 deopt_id != Isolate::kNoDeoptId ? call->env() : NULL, 1666 deopt_id != Isolate::kNoDeoptId ? call->env() : NULL,
1667 Definition::kValue); 1667 FlowGraph::kValue);
1668 1668
1669 if (array_cid == kTypedDataFloat32ArrayCid) { 1669 if (array_cid == kTypedDataFloat32ArrayCid) {
1670 *last = new FloatToDoubleInstr(new Value(*last), deopt_id); 1670 *last = new FloatToDoubleInstr(new Value(*last), deopt_id);
1671 flow_graph()->AppendTo(cursor, 1671 flow_graph()->AppendTo(cursor,
1672 *last, 1672 *last,
1673 deopt_id != Isolate::kNoDeoptId ? call->env() : NULL, 1673 deopt_id != Isolate::kNoDeoptId ? call->env() : NULL,
1674 Definition::kValue); 1674 FlowGraph::kValue);
1675 } 1675 }
1676 return true; 1676 return true;
1677 } 1677 }
1678 1678
1679 1679
1680 bool FlowGraphOptimizer::TryReplaceWithLoadIndexed(InstanceCallInstr* call) { 1680 bool FlowGraphOptimizer::TryReplaceWithLoadIndexed(InstanceCallInstr* call) {
1681 // Check for monomorphic IC data. 1681 // Check for monomorphic IC data.
1682 if (!call->HasICData()) return false; 1682 if (!call->HasICData()) return false;
1683 const ICData& ic_data = ICData::Handle(call->ic_data()->AsUnaryClassChecks()); 1683 const ICData& ic_data = ICData::Handle(call->ic_data()->AsUnaryClassChecks());
1684 if (ic_data.NumberOfChecks() != 1) return false; 1684 if (ic_data.NumberOfChecks() != 1) return false;
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1788 ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecksForArgNr(1)); 1788 ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecksForArgNr(1));
1789 AddCheckClass(right, 1789 AddCheckClass(right,
1790 unary_checks_1, 1790 unary_checks_1,
1791 call->deopt_id(), 1791 call->deopt_id(),
1792 call->env(), 1792 call->env(),
1793 call); 1793 call);
1794 // String-to-char-code instructions returns -1 (illegal charcode) if 1794 // String-to-char-code instructions returns -1 (illegal charcode) if
1795 // string is not of length one. 1795 // string is not of length one.
1796 StringToCharCodeInstr* char_code_right = 1796 StringToCharCodeInstr* char_code_right =
1797 new StringToCharCodeInstr(new Value(right), kOneByteStringCid); 1797 new StringToCharCodeInstr(new Value(right), kOneByteStringCid);
1798 InsertBefore(call, char_code_right, call->env(), Definition::kValue); 1798 InsertBefore(call, char_code_right, call->env(), FlowGraph::kValue);
1799 right_val = new Value(char_code_right); 1799 right_val = new Value(char_code_right);
1800 } 1800 }
1801 1801
1802 // Comparing char-codes instead of strings. 1802 // Comparing char-codes instead of strings.
1803 EqualityCompareInstr* comp = 1803 EqualityCompareInstr* comp =
1804 new EqualityCompareInstr(call->token_pos(), 1804 new EqualityCompareInstr(call->token_pos(),
1805 op_kind, 1805 op_kind,
1806 left_val, 1806 left_val,
1807 right_val, 1807 right_val,
1808 kSmiCid, 1808 kSmiCid,
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1843 return true; 1843 return true;
1844 } else { 1844 } else {
1845 return false; 1845 return false;
1846 } 1846 }
1847 } else if (HasOnlyTwoOf(ic_data, kSmiCid)) { 1847 } else if (HasOnlyTwoOf(ic_data, kSmiCid)) {
1848 InsertBefore(call, 1848 InsertBefore(call,
1849 new CheckSmiInstr(new Value(left), 1849 new CheckSmiInstr(new Value(left),
1850 call->deopt_id(), 1850 call->deopt_id(),
1851 call->token_pos()), 1851 call->token_pos()),
1852 call->env(), 1852 call->env(),
1853 Definition::kEffect); 1853 FlowGraph::kEffect);
1854 InsertBefore(call, 1854 InsertBefore(call,
1855 new CheckSmiInstr(new Value(right), 1855 new CheckSmiInstr(new Value(right),
1856 call->deopt_id(), 1856 call->deopt_id(),
1857 call->token_pos()), 1857 call->token_pos()),
1858 call->env(), 1858 call->env(),
1859 Definition::kEffect); 1859 FlowGraph::kEffect);
1860 cid = kSmiCid; 1860 cid = kSmiCid;
1861 } else if (HasTwoMintOrSmi(ic_data) && 1861 } else if (HasTwoMintOrSmi(ic_data) &&
1862 FlowGraphCompiler::SupportsUnboxedMints()) { 1862 FlowGraphCompiler::SupportsUnboxedMints()) {
1863 cid = kMintCid; 1863 cid = kMintCid;
1864 } else if (HasTwoDoubleOrSmi(ic_data) && CanUnboxDouble()) { 1864 } else if (HasTwoDoubleOrSmi(ic_data) && CanUnboxDouble()) {
1865 // Use double comparison. 1865 // Use double comparison.
1866 if (SmiFitsInDouble()) { 1866 if (SmiFitsInDouble()) {
1867 cid = kDoubleCid; 1867 cid = kDoubleCid;
1868 } else { 1868 } else {
1869 if (ICDataHasReceiverArgumentClassIds(ic_data, kSmiCid, kSmiCid)) { 1869 if (ICDataHasReceiverArgumentClassIds(ic_data, kSmiCid, kSmiCid)) {
1870 // We cannot use double comparison on two smis. Need polymorphic 1870 // We cannot use double comparison on two smis. Need polymorphic
1871 // call. 1871 // call.
1872 return false; 1872 return false;
1873 } else { 1873 } else {
1874 InsertBefore(call, 1874 InsertBefore(call,
1875 new CheckEitherNonSmiInstr(new Value(left), 1875 new CheckEitherNonSmiInstr(new Value(left),
1876 new Value(right), 1876 new Value(right),
1877 call->deopt_id()), 1877 call->deopt_id()),
1878 call->env(), 1878 call->env(),
1879 Definition::kEffect); 1879 FlowGraph::kEffect);
1880 cid = kDoubleCid; 1880 cid = kDoubleCid;
1881 } 1881 }
1882 } 1882 }
1883 } else { 1883 } else {
1884 // Check if ICDData contains checks with Smi/Null combinations. In that case 1884 // Check if ICDData contains checks with Smi/Null combinations. In that case
1885 // we can still emit the optimized Smi equality operation but need to add 1885 // we can still emit the optimized Smi equality operation but need to add
1886 // checks for null or Smi. 1886 // checks for null or Smi.
1887 GrowableArray<intptr_t> smi_or_null(2); 1887 GrowableArray<intptr_t> smi_or_null(2);
1888 smi_or_null.Add(kSmiCid); 1888 smi_or_null.Add(kSmiCid);
1889 smi_or_null.Add(kNullCid); 1889 smi_or_null.Add(kNullCid);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1945 Definition* left = call->ArgumentAt(0); 1945 Definition* left = call->ArgumentAt(0);
1946 Definition* right = call->ArgumentAt(1); 1946 Definition* right = call->ArgumentAt(1);
1947 1947
1948 intptr_t cid = kIllegalCid; 1948 intptr_t cid = kIllegalCid;
1949 if (HasOnlyTwoOf(ic_data, kSmiCid)) { 1949 if (HasOnlyTwoOf(ic_data, kSmiCid)) {
1950 InsertBefore(call, 1950 InsertBefore(call,
1951 new CheckSmiInstr(new Value(left), 1951 new CheckSmiInstr(new Value(left),
1952 call->deopt_id(), 1952 call->deopt_id(),
1953 call->token_pos()), 1953 call->token_pos()),
1954 call->env(), 1954 call->env(),
1955 Definition::kEffect); 1955 FlowGraph::kEffect);
1956 InsertBefore(call, 1956 InsertBefore(call,
1957 new CheckSmiInstr(new Value(right), 1957 new CheckSmiInstr(new Value(right),
1958 call->deopt_id(), 1958 call->deopt_id(),
1959 call->token_pos()), 1959 call->token_pos()),
1960 call->env(), 1960 call->env(),
1961 Definition::kEffect); 1961 FlowGraph::kEffect);
1962 cid = kSmiCid; 1962 cid = kSmiCid;
1963 } else if (HasTwoMintOrSmi(ic_data) && 1963 } else if (HasTwoMintOrSmi(ic_data) &&
1964 FlowGraphCompiler::SupportsUnboxedMints()) { 1964 FlowGraphCompiler::SupportsUnboxedMints()) {
1965 cid = kMintCid; 1965 cid = kMintCid;
1966 } else if (HasTwoDoubleOrSmi(ic_data) && CanUnboxDouble()) { 1966 } else if (HasTwoDoubleOrSmi(ic_data) && CanUnboxDouble()) {
1967 // Use double comparison. 1967 // Use double comparison.
1968 if (SmiFitsInDouble()) { 1968 if (SmiFitsInDouble()) {
1969 cid = kDoubleCid; 1969 cid = kDoubleCid;
1970 } else { 1970 } else {
1971 if (ICDataHasReceiverArgumentClassIds(ic_data, kSmiCid, kSmiCid)) { 1971 if (ICDataHasReceiverArgumentClassIds(ic_data, kSmiCid, kSmiCid)) {
1972 // We cannot use double comparison on two smis. Need polymorphic 1972 // We cannot use double comparison on two smis. Need polymorphic
1973 // call. 1973 // call.
1974 return false; 1974 return false;
1975 } else { 1975 } else {
1976 InsertBefore(call, 1976 InsertBefore(call,
1977 new CheckEitherNonSmiInstr(new Value(left), 1977 new CheckEitherNonSmiInstr(new Value(left),
1978 new Value(right), 1978 new Value(right),
1979 call->deopt_id()), 1979 call->deopt_id()),
1980 call->env(), 1980 call->env(),
1981 Definition::kEffect); 1981 FlowGraph::kEffect);
1982 cid = kDoubleCid; 1982 cid = kDoubleCid;
1983 } 1983 }
1984 } 1984 }
1985 } else { 1985 } else {
1986 return false; 1986 return false;
1987 } 1987 }
1988 ASSERT(cid != kIllegalCid); 1988 ASSERT(cid != kIllegalCid);
1989 RelationalOpInstr* comp = new RelationalOpInstr(call->token_pos(), 1989 RelationalOpInstr* comp = new RelationalOpInstr(call->token_pos(),
1990 op_kind, 1990 op_kind,
1991 new Value(left), 1991 new Value(left),
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
2121 } 2121 }
2122 // Check that either left or right are not a smi. Result of a 2122 // Check that either left or right are not a smi. Result of a
2123 // binary operation with two smis is a smi not a double, except '/' which 2123 // binary operation with two smis is a smi not a double, except '/' which
2124 // returns a double for two smis. 2124 // returns a double for two smis.
2125 if (op_kind != Token::kDIV) { 2125 if (op_kind != Token::kDIV) {
2126 InsertBefore(call, 2126 InsertBefore(call,
2127 new CheckEitherNonSmiInstr(new Value(left), 2127 new CheckEitherNonSmiInstr(new Value(left),
2128 new Value(right), 2128 new Value(right),
2129 call->deopt_id()), 2129 call->deopt_id()),
2130 call->env(), 2130 call->env(),
2131 Definition::kEffect); 2131 FlowGraph::kEffect);
2132 } 2132 }
2133 2133
2134 BinaryDoubleOpInstr* double_bin_op = 2134 BinaryDoubleOpInstr* double_bin_op =
2135 new BinaryDoubleOpInstr(op_kind, new Value(left), new Value(right), 2135 new BinaryDoubleOpInstr(op_kind, new Value(left), new Value(right),
2136 call->deopt_id(), call->token_pos()); 2136 call->deopt_id(), call->token_pos());
2137 ReplaceCall(call, double_bin_op); 2137 ReplaceCall(call, double_bin_op);
2138 } else if (operands_type == kMintCid) { 2138 } else if (operands_type == kMintCid) {
2139 if (!FlowGraphCompiler::SupportsUnboxedMints()) return false; 2139 if (!FlowGraphCompiler::SupportsUnboxedMints()) return false;
2140 if ((op_kind == Token::kSHR) || (op_kind == Token::kSHL)) { 2140 if ((op_kind == Token::kSHR) || (op_kind == Token::kSHL)) {
2141 ShiftMintOpInstr* shift_op = 2141 ShiftMintOpInstr* shift_op =
(...skipping 17 matching lines...) Expand all
2159 if (right->IsConstant()) { 2159 if (right->IsConstant()) {
2160 const Object& obj = right->AsConstant()->value(); 2160 const Object& obj = right->AsConstant()->value();
2161 if (obj.IsSmi() && Utils::IsPowerOfTwo(Smi::Cast(obj).Value())) { 2161 if (obj.IsSmi() && Utils::IsPowerOfTwo(Smi::Cast(obj).Value())) {
2162 // Insert smi check and attach a copy of the original environment 2162 // Insert smi check and attach a copy of the original environment
2163 // because the smi operation can still deoptimize. 2163 // because the smi operation can still deoptimize.
2164 InsertBefore(call, 2164 InsertBefore(call,
2165 new CheckSmiInstr(new Value(left), 2165 new CheckSmiInstr(new Value(left),
2166 call->deopt_id(), 2166 call->deopt_id(),
2167 call->token_pos()), 2167 call->token_pos()),
2168 call->env(), 2168 call->env(),
2169 Definition::kEffect); 2169 FlowGraph::kEffect);
2170 ConstantInstr* constant = 2170 ConstantInstr* constant =
2171 flow_graph()->GetConstant(Smi::Handle( 2171 flow_graph()->GetConstant(Smi::Handle(
2172 Smi::New(Smi::Cast(obj).Value() - 1))); 2172 Smi::New(Smi::Cast(obj).Value() - 1)));
2173 BinarySmiOpInstr* bin_op = 2173 BinarySmiOpInstr* bin_op =
2174 new BinarySmiOpInstr(Token::kBIT_AND, 2174 new BinarySmiOpInstr(Token::kBIT_AND,
2175 new Value(left), 2175 new Value(left),
2176 new Value(constant), 2176 new Value(constant),
2177 call->deopt_id(), 2177 call->deopt_id(),
2178 call->token_pos()); 2178 call->token_pos());
2179 ReplaceCall(call, bin_op); 2179 ReplaceCall(call, bin_op);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2214 Token::Kind op_kind) { 2214 Token::Kind op_kind) {
2215 ASSERT(call->ArgumentCount() == 1); 2215 ASSERT(call->ArgumentCount() == 1);
2216 Definition* input = call->ArgumentAt(0); 2216 Definition* input = call->ArgumentAt(0);
2217 Definition* unary_op = NULL; 2217 Definition* unary_op = NULL;
2218 if (HasOnlyOneSmi(*call->ic_data())) { 2218 if (HasOnlyOneSmi(*call->ic_data())) {
2219 InsertBefore(call, 2219 InsertBefore(call,
2220 new CheckSmiInstr(new Value(input), 2220 new CheckSmiInstr(new Value(input),
2221 call->deopt_id(), 2221 call->deopt_id(),
2222 call->token_pos()), 2222 call->token_pos()),
2223 call->env(), 2223 call->env(),
2224 Definition::kEffect); 2224 FlowGraph::kEffect);
2225 unary_op = new UnarySmiOpInstr(op_kind, new Value(input), call->deopt_id()); 2225 unary_op = new UnarySmiOpInstr(op_kind, new Value(input), call->deopt_id());
2226 } else if ((op_kind == Token::kBIT_NOT) && 2226 } else if ((op_kind == Token::kBIT_NOT) &&
2227 HasOnlySmiOrMint(*call->ic_data()) && 2227 HasOnlySmiOrMint(*call->ic_data()) &&
2228 FlowGraphCompiler::SupportsUnboxedMints()) { 2228 FlowGraphCompiler::SupportsUnboxedMints()) {
2229 unary_op = new UnaryMintOpInstr( 2229 unary_op = new UnaryMintOpInstr(
2230 op_kind, new Value(input), call->deopt_id()); 2230 op_kind, new Value(input), call->deopt_id());
2231 } else if (HasOnlyOneDouble(*call->ic_data()) && 2231 } else if (HasOnlyOneDouble(*call->ic_data()) &&
2232 (op_kind == Token::kNEGATE) && 2232 (op_kind == Token::kNEGATE) &&
2233 CanUnboxDouble()) { 2233 CanUnboxDouble()) {
2234 AddReceiverCheck(call); 2234 AddReceiverCheck(call);
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after
2701 intptr_t cid, 2701 intptr_t cid,
2702 Definition* str, 2702 Definition* str,
2703 Definition* index, 2703 Definition* index,
2704 Instruction* cursor) { 2704 Instruction* cursor) {
2705 2705
2706 cursor = flow_graph()->AppendTo(cursor, 2706 cursor = flow_graph()->AppendTo(cursor,
2707 new CheckSmiInstr(new Value(index), 2707 new CheckSmiInstr(new Value(index),
2708 call->deopt_id(), 2708 call->deopt_id(),
2709 call->token_pos()), 2709 call->token_pos()),
2710 call->env(), 2710 call->env(),
2711 Definition::kEffect); 2711 FlowGraph::kEffect);
2712 2712
2713 // Load the length of the string. 2713 // Load the length of the string.
2714 LoadFieldInstr* length = BuildLoadStringLength(str); 2714 LoadFieldInstr* length = BuildLoadStringLength(str);
2715 cursor = flow_graph()->AppendTo(cursor, length, NULL, Definition::kValue); 2715 cursor = flow_graph()->AppendTo(cursor, length, NULL, FlowGraph::kValue);
2716 // Bounds check. 2716 // Bounds check.
2717 cursor = flow_graph()->AppendTo(cursor, 2717 cursor = flow_graph()->AppendTo(cursor,
2718 new CheckArrayBoundInstr(new Value(length), 2718 new CheckArrayBoundInstr(new Value(length),
2719 new Value(index), 2719 new Value(index),
2720 call->deopt_id()), 2720 call->deopt_id()),
2721 call->env(), 2721 call->env(),
2722 Definition::kEffect); 2722 FlowGraph::kEffect);
2723 2723
2724 LoadIndexedInstr* load_indexed = new LoadIndexedInstr( 2724 LoadIndexedInstr* load_indexed = new LoadIndexedInstr(
2725 new Value(str), 2725 new Value(str),
2726 new Value(index), 2726 new Value(index),
2727 FlowGraphCompiler::ElementSizeFor(cid), 2727 FlowGraphCompiler::ElementSizeFor(cid),
2728 cid, 2728 cid,
2729 Isolate::kNoDeoptId, 2729 Isolate::kNoDeoptId,
2730 call->token_pos()); 2730 call->token_pos());
2731 2731
2732 cursor = flow_graph()->AppendTo(cursor, 2732 cursor = flow_graph()->AppendTo(cursor,
2733 load_indexed, 2733 load_indexed,
2734 NULL, 2734 NULL,
2735 Definition::kValue); 2735 FlowGraph::kValue);
2736 ASSERT(cursor == load_indexed); 2736 ASSERT(cursor == load_indexed);
2737 return load_indexed; 2737 return load_indexed;
2738 } 2738 }
2739 2739
2740 2740
2741 bool FlowGraphOptimizer::InlineStringCodeUnitAt( 2741 bool FlowGraphOptimizer::InlineStringCodeUnitAt(
2742 Instruction* call, 2742 Instruction* call,
2743 intptr_t cid, 2743 intptr_t cid,
2744 TargetEntryInstr** entry, 2744 TargetEntryInstr** entry,
2745 Definition** last) { 2745 Definition** last) {
(...skipping 29 matching lines...) Expand all
2775 2775
2776 *entry = new TargetEntryInstr(flow_graph()->allocate_block_id(), 2776 *entry = new TargetEntryInstr(flow_graph()->allocate_block_id(),
2777 call->GetBlock()->try_index()); 2777 call->GetBlock()->try_index());
2778 (*entry)->InheritDeoptTarget(call); 2778 (*entry)->InheritDeoptTarget(call);
2779 2779
2780 *last = PrepareInlineStringIndexOp(call, cid, str, index, *entry); 2780 *last = PrepareInlineStringIndexOp(call, cid, str, index, *entry);
2781 2781
2782 StringFromCharCodeInstr* char_at = 2782 StringFromCharCodeInstr* char_at =
2783 new StringFromCharCodeInstr(new Value(*last), cid); 2783 new StringFromCharCodeInstr(new Value(*last), cid);
2784 2784
2785 flow_graph()->AppendTo(*last, char_at, NULL, Definition::kValue); 2785 flow_graph()->AppendTo(*last, char_at, NULL, FlowGraph::kValue);
2786 *last = char_at; 2786 *last = char_at;
2787 2787
2788 return true; 2788 return true;
2789 } 2789 }
2790 2790
2791 2791
2792 void FlowGraphOptimizer::ReplaceWithMathCFunction( 2792 void FlowGraphOptimizer::ReplaceWithMathCFunction(
2793 InstanceCallInstr* call, 2793 InstanceCallInstr* call,
2794 MethodRecognizer::Kind recognized_kind) { 2794 MethodRecognizer::Kind recognized_kind) {
2795 AddReceiverCheck(call); 2795 AddReceiverCheck(call);
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
3070 } 3070 }
3071 BinarySmiOpInstr* left_shift = 3071 BinarySmiOpInstr* left_shift =
3072 new BinarySmiOpInstr(Token::kSHL, 3072 new BinarySmiOpInstr(Token::kSHL,
3073 new Value(value), new Value(count), 3073 new Value(value), new Value(count),
3074 call->deopt_id(), call->token_pos()); 3074 call->deopt_id(), call->token_pos());
3075 left_shift->set_is_truncating(true); 3075 left_shift->set_is_truncating(true);
3076 if ((kBitsPerWord == 32) && (mask_value == 0xffffffffLL)) { 3076 if ((kBitsPerWord == 32) && (mask_value == 0xffffffffLL)) {
3077 // No BIT_AND operation needed. 3077 // No BIT_AND operation needed.
3078 ReplaceCall(call, left_shift); 3078 ReplaceCall(call, left_shift);
3079 } else { 3079 } else {
3080 InsertBefore(call, left_shift, call->env(), Definition::kValue); 3080 InsertBefore(call, left_shift, call->env(), FlowGraph::kValue);
3081 BinarySmiOpInstr* bit_and = 3081 BinarySmiOpInstr* bit_and =
3082 new BinarySmiOpInstr(Token::kBIT_AND, 3082 new BinarySmiOpInstr(Token::kBIT_AND,
3083 new Value(left_shift), new Value(int32_mask), 3083 new Value(left_shift), new Value(int32_mask),
3084 call->deopt_id(), call->token_pos()); 3084 call->deopt_id(), call->token_pos());
3085 ReplaceCall(call, bit_and); 3085 ReplaceCall(call, bit_and);
3086 } 3086 }
3087 return true; 3087 return true;
3088 } 3088 }
3089 3089
3090 if (HasTwoMintOrSmi(ic_data) && 3090 if (HasTwoMintOrSmi(ic_data) &&
3091 HasOnlyOneSmi(ICData::Handle(ic_data.AsUnaryClassChecksForArgNr(1)))) { 3091 HasOnlyOneSmi(ICData::Handle(ic_data.AsUnaryClassChecksForArgNr(1)))) {
3092 if (!FlowGraphCompiler::SupportsUnboxedMints() || 3092 if (!FlowGraphCompiler::SupportsUnboxedMints() ||
3093 ic_data.HasDeoptReason(ICData::kDeoptShiftMintOp)) { 3093 ic_data.HasDeoptReason(ICData::kDeoptShiftMintOp)) {
3094 return false; 3094 return false;
3095 } 3095 }
3096 ShiftMintOpInstr* left_shift = 3096 ShiftMintOpInstr* left_shift =
3097 new ShiftMintOpInstr(Token::kSHL, 3097 new ShiftMintOpInstr(Token::kSHL,
3098 new Value(value), new Value(count), 3098 new Value(value), new Value(count),
3099 call->deopt_id()); 3099 call->deopt_id());
3100 InsertBefore(call, left_shift, call->env(), Definition::kValue); 3100 InsertBefore(call, left_shift, call->env(), FlowGraph::kValue);
3101 BinaryMintOpInstr* bit_and = 3101 BinaryMintOpInstr* bit_and =
3102 new BinaryMintOpInstr(Token::kBIT_AND, 3102 new BinaryMintOpInstr(Token::kBIT_AND,
3103 new Value(left_shift), new Value(int32_mask), 3103 new Value(left_shift), new Value(int32_mask),
3104 call->deopt_id()); 3104 call->deopt_id());
3105 ReplaceCall(call, bit_and); 3105 ReplaceCall(call, bit_and);
3106 return true; 3106 return true;
3107 } 3107 }
3108 } 3108 }
3109 return false; 3109 return false;
3110 } 3110 }
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
3523 *last = new LoadIndexedInstr(new Value(array), 3523 *last = new LoadIndexedInstr(new Value(array),
3524 new Value(index), 3524 new Value(index),
3525 1, 3525 1,
3526 view_cid, 3526 view_cid,
3527 deopt_id, 3527 deopt_id,
3528 call->token_pos()); 3528 call->token_pos());
3529 cursor = flow_graph()->AppendTo( 3529 cursor = flow_graph()->AppendTo(
3530 cursor, 3530 cursor,
3531 *last, 3531 *last,
3532 deopt_id != Isolate::kNoDeoptId ? call->env() : NULL, 3532 deopt_id != Isolate::kNoDeoptId ? call->env() : NULL,
3533 Definition::kValue); 3533 FlowGraph::kValue);
3534 3534
3535 if (view_cid == kTypedDataFloat32ArrayCid) { 3535 if (view_cid == kTypedDataFloat32ArrayCid) {
3536 *last = new FloatToDoubleInstr(new Value(*last), deopt_id); 3536 *last = new FloatToDoubleInstr(new Value(*last), deopt_id);
3537 flow_graph()->AppendTo(cursor, 3537 flow_graph()->AppendTo(cursor,
3538 *last, 3538 *last,
3539 deopt_id != Isolate::kNoDeoptId ? call->env() : NULL, 3539 deopt_id != Isolate::kNoDeoptId ? call->env() : NULL,
3540 Definition::kValue); 3540 FlowGraph::kValue);
3541 } 3541 }
3542 return true; 3542 return true;
3543 } 3543 }
3544 3544
3545 3545
3546 bool FlowGraphOptimizer::InlineByteArrayViewStore(const Function& target, 3546 bool FlowGraphOptimizer::InlineByteArrayViewStore(const Function& target,
3547 Instruction* call, 3547 Instruction* call,
3548 Definition* receiver, 3548 Definition* receiver,
3549 intptr_t array_cid, 3549 intptr_t array_cid,
3550 intptr_t view_cid, 3550 intptr_t view_cid,
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
3649 AddCheckClass(stored_value, value_check, call->deopt_id(), call->env(), 3649 AddCheckClass(stored_value, value_check, call->deopt_id(), call->env(),
3650 call); 3650 call);
3651 } 3651 }
3652 3652
3653 if (view_cid == kTypedDataFloat32ArrayCid) { 3653 if (view_cid == kTypedDataFloat32ArrayCid) {
3654 stored_value = 3654 stored_value =
3655 new DoubleToFloatInstr(new Value(stored_value), call->deopt_id()); 3655 new DoubleToFloatInstr(new Value(stored_value), call->deopt_id());
3656 cursor = flow_graph()->AppendTo(cursor, 3656 cursor = flow_graph()->AppendTo(cursor,
3657 stored_value, 3657 stored_value,
3658 NULL, 3658 NULL,
3659 Definition::kValue); 3659 FlowGraph::kValue);
3660 } 3660 }
3661 3661
3662 StoreBarrierType needs_store_barrier = kNoStoreBarrier; 3662 StoreBarrierType needs_store_barrier = kNoStoreBarrier;
3663 *last = new StoreIndexedInstr(new Value(array), 3663 *last = new StoreIndexedInstr(new Value(array),
3664 new Value(index), 3664 new Value(index),
3665 new Value(stored_value), 3665 new Value(stored_value),
3666 needs_store_barrier, 3666 needs_store_barrier,
3667 1, // Index scale 3667 1, // Index scale
3668 view_cid, 3668 view_cid,
3669 call->deopt_id(), 3669 call->deopt_id(),
3670 call->token_pos()); 3670 call->token_pos());
3671 3671
3672 flow_graph()->AppendTo(cursor, 3672 flow_graph()->AppendTo(cursor,
3673 *last, 3673 *last,
3674 call->deopt_id() != Isolate::kNoDeoptId ? 3674 call->deopt_id() != Isolate::kNoDeoptId ?
3675 call->env() : NULL, 3675 call->env() : NULL,
3676 Definition::kEffect); 3676 FlowGraph::kEffect);
3677 return true; 3677 return true;
3678 } 3678 }
3679 3679
3680 3680
3681 3681
3682 intptr_t FlowGraphOptimizer::PrepareInlineByteArrayViewOp( 3682 intptr_t FlowGraphOptimizer::PrepareInlineByteArrayViewOp(
3683 Instruction* call, 3683 Instruction* call,
3684 intptr_t array_cid, 3684 intptr_t array_cid,
3685 intptr_t view_cid, 3685 intptr_t view_cid,
3686 Definition** array, 3686 Definition** array,
3687 Definition* byte_index, 3687 Definition* byte_index,
3688 Instruction** cursor) { 3688 Instruction** cursor) {
3689 // Insert byte_index smi check. 3689 // Insert byte_index smi check.
3690 *cursor = flow_graph()->AppendTo(*cursor, 3690 *cursor = flow_graph()->AppendTo(*cursor,
3691 new CheckSmiInstr(new Value(byte_index), 3691 new CheckSmiInstr(new Value(byte_index),
3692 call->deopt_id(), 3692 call->deopt_id(),
3693 call->token_pos()), 3693 call->token_pos()),
3694 call->env(), 3694 call->env(),
3695 Definition::kEffect); 3695 FlowGraph::kEffect);
3696 3696
3697 LoadFieldInstr* length = 3697 LoadFieldInstr* length =
3698 new LoadFieldInstr(new Value(*array), 3698 new LoadFieldInstr(new Value(*array),
3699 CheckArrayBoundInstr::LengthOffsetFor(array_cid), 3699 CheckArrayBoundInstr::LengthOffsetFor(array_cid),
3700 Type::ZoneHandle(Type::SmiType()), 3700 Type::ZoneHandle(Type::SmiType()),
3701 call->token_pos()); 3701 call->token_pos());
3702 length->set_is_immutable(true); 3702 length->set_is_immutable(true);
3703 length->set_result_cid(kSmiCid); 3703 length->set_result_cid(kSmiCid);
3704 length->set_recognized_kind( 3704 length->set_recognized_kind(
3705 LoadFieldInstr::RecognizedKindFromArrayCid(array_cid)); 3705 LoadFieldInstr::RecognizedKindFromArrayCid(array_cid));
3706 *cursor = flow_graph()->AppendTo(*cursor, 3706 *cursor = flow_graph()->AppendTo(*cursor,
3707 length, 3707 length,
3708 NULL, 3708 NULL,
3709 Definition::kValue); 3709 FlowGraph::kValue);
3710 3710
3711 intptr_t element_size = FlowGraphCompiler::ElementSizeFor(array_cid); 3711 intptr_t element_size = FlowGraphCompiler::ElementSizeFor(array_cid);
3712 ConstantInstr* bytes_per_element = 3712 ConstantInstr* bytes_per_element =
3713 flow_graph()->GetConstant(Smi::Handle(Smi::New(element_size))); 3713 flow_graph()->GetConstant(Smi::Handle(Smi::New(element_size)));
3714 BinarySmiOpInstr* len_in_bytes = 3714 BinarySmiOpInstr* len_in_bytes =
3715 new BinarySmiOpInstr(Token::kMUL, 3715 new BinarySmiOpInstr(Token::kMUL,
3716 new Value(length), 3716 new Value(length),
3717 new Value(bytes_per_element), 3717 new Value(bytes_per_element),
3718 call->deopt_id(), call->token_pos()); 3718 call->deopt_id(), call->token_pos());
3719 *cursor = flow_graph()->AppendTo(*cursor, len_in_bytes, call->env(), 3719 *cursor = flow_graph()->AppendTo(*cursor, len_in_bytes, call->env(),
3720 Definition::kValue); 3720 FlowGraph::kValue);
3721 3721
3722 ConstantInstr* length_adjustment = 3722 ConstantInstr* length_adjustment =
3723 flow_graph()->GetConstant(Smi::Handle(Smi::New( 3723 flow_graph()->GetConstant(Smi::Handle(Smi::New(
3724 FlowGraphCompiler::ElementSizeFor(view_cid) - 1))); 3724 FlowGraphCompiler::ElementSizeFor(view_cid) - 1)));
3725 // adjusted_length = len_in_bytes - (element_size - 1). 3725 // adjusted_length = len_in_bytes - (element_size - 1).
3726 BinarySmiOpInstr* adjusted_length = 3726 BinarySmiOpInstr* adjusted_length =
3727 new BinarySmiOpInstr(Token::kSUB, 3727 new BinarySmiOpInstr(Token::kSUB,
3728 new Value(len_in_bytes), 3728 new Value(len_in_bytes),
3729 new Value(length_adjustment), 3729 new Value(length_adjustment),
3730 call->deopt_id(), call->token_pos()); 3730 call->deopt_id(), call->token_pos());
3731 *cursor = flow_graph()->AppendTo(*cursor, adjusted_length, call->env(), 3731 *cursor = flow_graph()->AppendTo(*cursor, adjusted_length, call->env(),
3732 Definition::kValue); 3732 FlowGraph::kValue);
3733 3733
3734 // Check adjusted_length > 0. 3734 // Check adjusted_length > 0.
3735 ConstantInstr* zero = flow_graph()->GetConstant(Smi::Handle(Smi::New(0))); 3735 ConstantInstr* zero = flow_graph()->GetConstant(Smi::Handle(Smi::New(0)));
3736 *cursor = flow_graph()->AppendTo(*cursor, 3736 *cursor = flow_graph()->AppendTo(*cursor,
3737 new CheckArrayBoundInstr( 3737 new CheckArrayBoundInstr(
3738 new Value(adjusted_length), 3738 new Value(adjusted_length),
3739 new Value(zero), 3739 new Value(zero),
3740 call->deopt_id()), 3740 call->deopt_id()),
3741 call->env(), 3741 call->env(),
3742 Definition::kEffect); 3742 FlowGraph::kEffect);
3743 // Check 0 <= byte_index < adjusted_length. 3743 // Check 0 <= byte_index < adjusted_length.
3744 *cursor = flow_graph()->AppendTo(*cursor, 3744 *cursor = flow_graph()->AppendTo(*cursor,
3745 new CheckArrayBoundInstr( 3745 new CheckArrayBoundInstr(
3746 new Value(adjusted_length), 3746 new Value(adjusted_length),
3747 new Value(byte_index), 3747 new Value(byte_index),
3748 call->deopt_id()), 3748 call->deopt_id()),
3749 call->env(), 3749 call->env(),
3750 Definition::kEffect); 3750 FlowGraph::kEffect);
3751 3751
3752 if (RawObject::IsExternalTypedDataClassId(array_cid)) { 3752 if (RawObject::IsExternalTypedDataClassId(array_cid)) {
3753 LoadUntaggedInstr* elements = 3753 LoadUntaggedInstr* elements =
3754 new LoadUntaggedInstr(new Value(*array), 3754 new LoadUntaggedInstr(new Value(*array),
3755 ExternalTypedData::data_offset()); 3755 ExternalTypedData::data_offset());
3756 *cursor = flow_graph()->AppendTo(*cursor, 3756 *cursor = flow_graph()->AppendTo(*cursor,
3757 elements, 3757 elements,
3758 NULL, 3758 NULL,
3759 Definition::kValue); 3759 FlowGraph::kValue);
3760 *array = elements; 3760 *array = elements;
3761 } 3761 }
3762 return array_cid; 3762 return array_cid;
3763 } 3763 }
3764 3764
3765 3765
3766 bool FlowGraphOptimizer::BuildByteArrayViewLoad(InstanceCallInstr* call, 3766 bool FlowGraphOptimizer::BuildByteArrayViewLoad(InstanceCallInstr* call,
3767 intptr_t view_cid) { 3767 intptr_t view_cid) {
3768 const bool simd_view = (view_cid == kTypedDataFloat32x4ArrayCid) || 3768 const bool simd_view = (view_cid == kTypedDataFloat32x4ArrayCid) ||
3769 (view_cid == kTypedDataInt32x4ArrayCid); 3769 (view_cid == kTypedDataInt32x4ArrayCid);
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
3997 current_iterator()->RemoveCurrentFromGraph(); 3997 current_iterator()->RemoveCurrentFromGraph();
3998 return; 3998 return;
3999 } 3999 }
4000 } 4000 }
4001 4001
4002 if (TypeCheckAsClassEquality(type)) { 4002 if (TypeCheckAsClassEquality(type)) {
4003 LoadClassIdInstr* left_cid = new LoadClassIdInstr(new Value(left)); 4003 LoadClassIdInstr* left_cid = new LoadClassIdInstr(new Value(left));
4004 InsertBefore(call, 4004 InsertBefore(call,
4005 left_cid, 4005 left_cid,
4006 NULL, 4006 NULL,
4007 Definition::kValue); 4007 FlowGraph::kValue);
4008 const intptr_t type_cid = Class::Handle(type.type_class()).id(); 4008 const intptr_t type_cid = Class::Handle(type.type_class()).id();
4009 ConstantInstr* cid = 4009 ConstantInstr* cid =
4010 flow_graph()->GetConstant(Smi::Handle(Smi::New(type_cid))); 4010 flow_graph()->GetConstant(Smi::Handle(Smi::New(type_cid)));
4011 4011
4012 StrictCompareInstr* check_cid = 4012 StrictCompareInstr* check_cid =
4013 new StrictCompareInstr(call->token_pos(), 4013 new StrictCompareInstr(call->token_pos(),
4014 negate ? Token::kNE_STRICT : Token::kEQ_STRICT, 4014 negate ? Token::kNE_STRICT : Token::kEQ_STRICT,
4015 new Value(left_cid), 4015 new Value(left_cid),
4016 new Value(cid), 4016 new Value(cid),
4017 false); // No number check. 4017 false); // No number check.
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
4412 if (InstanceCallNeedsClassCheck(instr)) { 4412 if (InstanceCallNeedsClassCheck(instr)) {
4413 AddReceiverCheck(instr); 4413 AddReceiverCheck(instr);
4414 } 4414 }
4415 StoreBarrierType needs_store_barrier = kEmitStoreBarrier; 4415 StoreBarrierType needs_store_barrier = kEmitStoreBarrier;
4416 if (ArgIsAlways(kSmiCid, *instr->ic_data(), 1)) { 4416 if (ArgIsAlways(kSmiCid, *instr->ic_data(), 1)) {
4417 InsertBefore(instr, 4417 InsertBefore(instr,
4418 new CheckSmiInstr(new Value(instr->ArgumentAt(1)), 4418 new CheckSmiInstr(new Value(instr->ArgumentAt(1)),
4419 instr->deopt_id(), 4419 instr->deopt_id(),
4420 instr->token_pos()), 4420 instr->token_pos()),
4421 instr->env(), 4421 instr->env(),
4422 Definition::kEffect); 4422 FlowGraph::kEffect);
4423 needs_store_barrier = kNoStoreBarrier; 4423 needs_store_barrier = kNoStoreBarrier;
4424 } 4424 }
4425 4425
4426 if (field.guarded_cid() != kDynamicCid) { 4426 if (field.guarded_cid() != kDynamicCid) {
4427 InsertBefore(instr, 4427 InsertBefore(instr,
4428 new GuardFieldInstr(new Value(instr->ArgumentAt(1)), 4428 new GuardFieldInstr(new Value(instr->ArgumentAt(1)),
4429 field, 4429 field,
4430 instr->deopt_id()), 4430 instr->deopt_id()),
4431 instr->env(), 4431 instr->env(),
4432 Definition::kEffect); 4432 FlowGraph::kEffect);
4433 } 4433 }
4434 4434
4435 // Field guard was detached. 4435 // Field guard was detached.
4436 StoreInstanceFieldInstr* store = new StoreInstanceFieldInstr( 4436 StoreInstanceFieldInstr* store = new StoreInstanceFieldInstr(
4437 field, 4437 field,
4438 new Value(instr->ArgumentAt(0)), 4438 new Value(instr->ArgumentAt(0)),
4439 new Value(instr->ArgumentAt(1)), 4439 new Value(instr->ArgumentAt(1)),
4440 needs_store_barrier, 4440 needs_store_barrier,
4441 instr->token_pos()); 4441 instr->token_pos());
4442 4442
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
4710 4710
4711 4711
4712 ConstraintInstr* RangeAnalysis::InsertConstraintFor(Definition* defn, 4712 ConstraintInstr* RangeAnalysis::InsertConstraintFor(Definition* defn,
4713 Range* constraint_range, 4713 Range* constraint_range,
4714 Instruction* after) { 4714 Instruction* after) {
4715 // No need to constrain constants. 4715 // No need to constrain constants.
4716 if (defn->IsConstant()) return NULL; 4716 if (defn->IsConstant()) return NULL;
4717 4717
4718 ConstraintInstr* constraint = 4718 ConstraintInstr* constraint =
4719 new ConstraintInstr(new Value(defn), constraint_range); 4719 new ConstraintInstr(new Value(defn), constraint_range);
4720 flow_graph_->InsertAfter(after, constraint, NULL, Definition::kValue); 4720 flow_graph_->InsertAfter(after, constraint, NULL, FlowGraph::kValue);
4721 RenameDominatedUses(defn, constraint, constraint); 4721 RenameDominatedUses(defn, constraint, constraint);
4722 constraints_.Add(constraint); 4722 constraints_.Add(constraint);
4723 return constraint; 4723 return constraint;
4724 } 4724 }
4725 4725
4726 4726
4727 void RangeAnalysis::ConstrainValueAfterBranch(Definition* defn, Value* use) { 4727 void RangeAnalysis::ConstrainValueAfterBranch(Definition* defn, Value* use) {
4728 BranchInstr* branch = use->instruction()->AsBranch(); 4728 BranchInstr* branch = use->instruction()->AsBranch();
4729 RelationalOpInstr* rel_op = branch->comparison()->AsRelationalOp(); 4729 RelationalOpInstr* rel_op = branch->comparison()->AsRelationalOp();
4730 if ((rel_op != NULL) && (rel_op->operation_cid() == kSmiCid)) { 4730 if ((rel_op != NULL) && (rel_op->operation_cid() == kSmiCid)) {
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
5149 current->DebugName(), 5149 current->DebugName(),
5150 current->GetDeoptId(), 5150 current->GetDeoptId(),
5151 current->GetBlock()->block_id(), 5151 current->GetBlock()->block_id(),
5152 pre_header->block_id()); 5152 pre_header->block_id());
5153 } 5153 }
5154 // Move the instruction out of the loop. 5154 // Move the instruction out of the loop.
5155 current->RemoveEnvironment(); 5155 current->RemoveEnvironment();
5156 it->RemoveCurrentFromGraph(); 5156 it->RemoveCurrentFromGraph();
5157 GotoInstr* last = pre_header->last_instruction()->AsGoto(); 5157 GotoInstr* last = pre_header->last_instruction()->AsGoto();
5158 // Using kind kEffect will not assign a fresh ssa temporary index. 5158 // Using kind kEffect will not assign a fresh ssa temporary index.
5159 flow_graph()->InsertBefore(last, current, last->env(), Definition::kEffect); 5159 flow_graph()->InsertBefore(last, current, last->env(), FlowGraph::kEffect);
5160 current->deopt_id_ = last->GetDeoptId(); 5160 current->deopt_id_ = last->GetDeoptId();
5161 } 5161 }
5162 5162
5163 5163
5164 void LICM::TryHoistCheckSmiThroughPhi(ForwardInstructionIterator* it, 5164 void LICM::TryHoistCheckSmiThroughPhi(ForwardInstructionIterator* it,
5165 BlockEntryInstr* header, 5165 BlockEntryInstr* header,
5166 BlockEntryInstr* pre_header, 5166 BlockEntryInstr* pre_header,
5167 CheckSmiInstr* current) { 5167 CheckSmiInstr* current) {
5168 PhiInstr* phi = current->value()->definition()->AsPhi(); 5168 PhiInstr* phi = current->value()->definition()->AsPhi();
5169 if (!header->loop_info()->Contains(phi->block()->preorder_number())) { 5169 if (!header->loop_info()->Contains(phi->block()->preorder_number())) {
(...skipping 4218 matching lines...) Expand 10 before | Expand all | Expand 10 after
9388 ComparisonInstr* new_comparison = 9388 ComparisonInstr* new_comparison =
9389 comparison->CopyWithNewOperands(comparison->left()->Copy(), 9389 comparison->CopyWithNewOperands(comparison->left()->Copy(),
9390 comparison->right()->Copy()); 9390 comparison->right()->Copy());
9391 IfThenElseInstr* if_then_else = new IfThenElseInstr( 9391 IfThenElseInstr* if_then_else = new IfThenElseInstr(
9392 new_comparison, 9392 new_comparison,
9393 if_true->Copy(), 9393 if_true->Copy(),
9394 if_false->Copy()); 9394 if_false->Copy());
9395 flow_graph->InsertBefore(branch, 9395 flow_graph->InsertBefore(branch,
9396 if_then_else, 9396 if_then_else,
9397 NULL, 9397 NULL,
9398 Definition::kValue); 9398 FlowGraph::kValue);
9399 9399
9400 phi->ReplaceUsesWith(if_then_else); 9400 phi->ReplaceUsesWith(if_then_else);
9401 9401
9402 // Connect IfThenElseInstr to the first instruction in the merge block 9402 // Connect IfThenElseInstr to the first instruction in the merge block
9403 // effectively eliminating diamond control flow. 9403 // effectively eliminating diamond control flow.
9404 // Current block as well as pred1 and pred2 blocks are no longer in 9404 // Current block as well as pred1 and pred2 blocks are no longer in
9405 // the graph at this point. 9405 // the graph at this point.
9406 if_then_else->LinkTo(join->next()); 9406 if_then_else->LinkTo(join->next());
9407 pred->set_last_instruction(join->last_instruction()); 9407 pred->set_last_instruction(join->last_instruction());
9408 9408
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
9633 LoadFieldInstr* load = slots[i]->IsField() 9633 LoadFieldInstr* load = slots[i]->IsField()
9634 ? new LoadFieldInstr(new Value(alloc), 9634 ? new LoadFieldInstr(new Value(alloc),
9635 &Field::Cast(*slots[i]), 9635 &Field::Cast(*slots[i]),
9636 AbstractType::ZoneHandle(), 9636 AbstractType::ZoneHandle(),
9637 alloc->token_pos()) 9637 alloc->token_pos())
9638 : new LoadFieldInstr(new Value(alloc), 9638 : new LoadFieldInstr(new Value(alloc),
9639 Smi::Cast(*slots[i]).Value(), 9639 Smi::Cast(*slots[i]).Value(),
9640 AbstractType::ZoneHandle(), 9640 AbstractType::ZoneHandle(),
9641 alloc->token_pos()); 9641 alloc->token_pos());
9642 flow_graph_->InsertBefore( 9642 flow_graph_->InsertBefore(
9643 exit, load, NULL, Definition::kValue); 9643 exit, load, NULL, FlowGraph::kValue);
9644 values->Add(new Value(load)); 9644 values->Add(new Value(load));
9645 } 9645 }
9646 9646
9647 MaterializeObjectInstr* mat = new MaterializeObjectInstr(cls, slots, values); 9647 MaterializeObjectInstr* mat = new MaterializeObjectInstr(cls, slots, values);
9648 flow_graph_->InsertBefore(exit, mat, NULL, Definition::kValue); 9648 flow_graph_->InsertBefore(exit, mat, NULL, FlowGraph::kValue);
9649 9649
9650 // Replace all mentions of this allocation with a newly inserted 9650 // Replace all mentions of this allocation with a newly inserted
9651 // MaterializeObject instruction. 9651 // MaterializeObject instruction.
9652 // We must preserve the identity: all mentions are replaced by the same 9652 // We must preserve the identity: all mentions are replaced by the same
9653 // materialization. 9653 // materialization.
9654 for (Environment::DeepIterator env_it(exit->env()); 9654 for (Environment::DeepIterator env_it(exit->env());
9655 !env_it.Done(); 9655 !env_it.Done();
9656 env_it.Advance()) { 9656 env_it.Advance()) {
9657 Value* use = env_it.CurrentValue(); 9657 Value* use = env_it.CurrentValue();
9658 if (use->definition() == alloc) { 9658 if (use->definition() == alloc) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
9698 } 9698 }
9699 9699
9700 // Insert materializations at environment uses. 9700 // Insert materializations at environment uses.
9701 for (intptr_t i = 0; i < exits.length(); i++) { 9701 for (intptr_t i = 0; i < exits.length(); i++) {
9702 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *slots); 9702 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *slots);
9703 } 9703 }
9704 } 9704 }
9705 9705
9706 9706
9707 } // namespace dart 9707 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698