Chromium Code Reviews| Index: runtime/vm/flow_graph_optimizer.cc |
| diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc |
| index bc91a15a2dc91bdc6a982a58e21353fdf6452a57..28dde79ac65b410ed2dda20c8e8960ae04a093e2 100644 |
| --- a/runtime/vm/flow_graph_optimizer.cc |
| +++ b/runtime/vm/flow_graph_optimizer.cc |
| @@ -63,6 +63,14 @@ static bool CanUnboxDouble() { |
| } |
| +static bool CanConvertUnboxedMintToDouble() { |
| +#if defined(TARGET_ARCH_IA32) |
| + return true; |
| +#else |
|
Florian Schneider
2014/09/19 09:49:00
I think there should be a TODO for the other platf
Cutch
2014/09/19 16:17:41
Added a note about ARM and a TODO to check for MIP
|
| + return false; |
| +#endif |
| +} |
| + |
| // Optimize instance calls using ICData. |
| void FlowGraphOptimizer::ApplyICData() { |
| VisitBlocks(); |
| @@ -637,21 +645,21 @@ void FlowGraphOptimizer::InsertConversion(Representation from, |
| converted = new UnboxUint32Instr(use->CopyWithType(), deopt_id); |
| } else if (from == kUnboxedMint && to == kUnboxedDouble) { |
| ASSERT(CanUnboxDouble()); |
| - // Convert by boxing/unboxing. |
| - // TODO(fschneider): Implement direct unboxed mint-to-double conversion. |
| - BoxIntegerInstr* boxed = |
| - new(I) BoxIntegerInstr(use->CopyWithType()); |
| - use->BindTo(boxed); |
| - InsertBefore(insert_before, boxed, NULL, FlowGraph::kValue); |
| - |
| const intptr_t deopt_id = (deopt_target != NULL) ? |
| deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; |
| - converted = new(I) UnboxDoubleInstr(new(I) Value(boxed), deopt_id); |
| - |
| + if (CanConvertUnboxedMintToDouble()) { |
| + // Fast path. |
| + converted = new MintToDoubleInstr(use->CopyWithType(), deopt_id); |
| + } else { |
| + // Slow path. |
| + BoxIntegerInstr* boxed = new(I) BoxIntegerInstr(use->CopyWithType()); |
| + use->BindTo(boxed); |
| + InsertBefore(insert_before, boxed, NULL, FlowGraph::kValue); |
| + converted = new(I) UnboxDoubleInstr(new(I) Value(boxed), deopt_id); |
| + } |
| } else if ((from == kUnboxedDouble) && (to == kTagged)) { |
| ASSERT(CanUnboxDouble()); |
| converted = new(I) BoxDoubleInstr(use->CopyWithType()); |
| - |
| } else if ((from == kTagged) && (to == kUnboxedDouble)) { |
| ASSERT(CanUnboxDouble()); |
| ASSERT((deopt_target != NULL) || |
| @@ -3051,14 +3059,21 @@ bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { |
| if (CanUnboxDouble() && |
| (recognized_kind == MethodRecognizer::kIntegerToDouble) && |
| - (ic_data.NumberOfChecks() == 1) && |
| - (class_ids[0] == kSmiCid)) { |
| - AddReceiverCheck(call); |
| - ReplaceCall(call, |
| - new(I) SmiToDoubleInstr( |
| - new(I) Value(call->ArgumentAt(0)), |
| - call->token_pos())); |
| - return true; |
| + (ic_data.NumberOfChecks() == 1)) { |
| + if (class_ids[0] == kSmiCid) { |
| + AddReceiverCheck(call); |
| + ReplaceCall(call, |
| + new(I) SmiToDoubleInstr( |
| + new(I) Value(call->ArgumentAt(0)), |
| + call->token_pos())); |
| + return true; |
| + } else if ((class_ids[0] == kMintCid) && CanConvertUnboxedMintToDouble()) { |
| + AddReceiverCheck(call); |
| + ReplaceCall(call, |
| + new(I) MintToDoubleInstr(new(I) Value(call->ArgumentAt(0)), |
| + call->deopt_id())); |
| + return true; |
| + } |
| } |
| if (class_ids[0] == kDoubleCid) { |
| @@ -4504,18 +4519,20 @@ void FlowGraphOptimizer::VisitStaticCall(StaticCallInstr* call) { |
| } else if (recognized_kind == MethodRecognizer::kDoubleFromInteger) { |
| if (call->HasICData() && (call->ic_data()->NumberOfChecks() == 1)) { |
| const ICData& ic_data = *call->ic_data(); |
| - if (CanUnboxDouble() && ArgIsAlways(kSmiCid, ic_data, 0)) { |
| - Definition* arg = call->ArgumentAt(0); |
| - InsertBefore(call, |
| - new(I) CheckSmiInstr( |
| - new(I) Value(arg), |
| - call->deopt_id(), |
| - call->token_pos()), |
| - call->env(), |
| - FlowGraph::kEffect); |
| - ReplaceCall(call, |
| - new(I) SmiToDoubleInstr(new(I) Value(arg), |
| - call->token_pos())); |
| + if (CanUnboxDouble()) { |
| + if (ArgIsAlways(kSmiCid, ic_data, 1)) { |
| + Definition* arg = call->ArgumentAt(1); |
| + AddCheckSmi(arg, call->deopt_id(), call->env(), call); |
| + ReplaceCall(call, |
| + new(I) SmiToDoubleInstr(new(I) Value(arg), |
| + call->token_pos())); |
| + } else if (ArgIsAlways(kMintCid, ic_data, 1) && |
| + CanConvertUnboxedMintToDouble()) { |
| + Definition* arg = call->ArgumentAt(1); |
| + ReplaceCall(call, |
| + new(I) MintToDoubleInstr(new(I) Value(arg), |
| + call->deopt_id())); |
| + } |
| } |
| } |
| } else if (call->function().IsFactory()) { |
| @@ -8424,6 +8441,17 @@ void ConstantPropagator::VisitSmiToDouble(SmiToDoubleInstr* instr) { |
| } |
| +void ConstantPropagator::VisitMintToDouble(MintToDoubleInstr* instr) { |
| + const Object& value = instr->value()->definition()->constant_value(); |
| + if (IsConstant(value) && value.IsInteger()) { |
| + SetValue(instr, Double::Handle(I, |
| + Double::New(Integer::Cast(value).AsDoubleValue(), Heap::kOld))); |
| + } else if (IsNonConstant(value)) { |
| + SetValue(instr, non_constant_); |
| + } |
| +} |
| + |
| + |
| void ConstantPropagator::VisitInt32ToDouble(Int32ToDoubleInstr* instr) { |
| const Object& value = instr->value()->definition()->constant_value(); |
| if (IsConstant(value) && value.IsInteger()) { |