| OLD | NEW | 
|---|
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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 | 
| OLD | NEW | 
|---|