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 beab25141223ed87757ff4bfd3756c0c5e6028b3..a4a9d0101e5bc264bdf5077331c5cdba58c5651a 100644 |
| --- a/runtime/vm/flow_graph_optimizer.cc |
| +++ b/runtime/vm/flow_graph_optimizer.cc |
| @@ -1274,6 +1274,22 @@ LoadIndexedInstr* FlowGraphOptimizer::BuildStringCharCodeAt( |
| } |
| +void FlowGraphOptimizer::ReplaceWithMathCFunction( |
| + InstanceCallInstr* call, |
| + MethodRecognizer::Kind recognized_kind) { |
| + AddCheckClass(call, call->ArgumentAt(0)->value()->Copy()); |
| + ZoneGrowableArray<Value*>* args = |
| + new ZoneGrowableArray<Value*>(call->ArgumentCount()); |
| + for (intptr_t i = 0; i < call->ArgumentCount(); i++) { |
| + args->Add(call->ArgumentAt(i)->value()); |
| + } |
| + InvokeMathCFunctionInstr* invoke = |
| + new InvokeMathCFunctionInstr(args, call, recognized_kind); |
| + call->ReplaceWith(invoke, current_iterator()); |
| + RemovePushArguments(call); |
| +} |
| + |
| + |
| // Inline only simple, frequently called core library methods. |
| bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { |
| ASSERT(call->HasICData()); |
| @@ -1321,38 +1337,48 @@ bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { |
| } |
| if (class_ids[0] == kDoubleCid) { |
| - if (recognized_kind == MethodRecognizer::kDoubleToInteger) { |
| - AddCheckClass(call, call->ArgumentAt(0)->value()->Copy()); |
| - ASSERT(call->HasICData()); |
| - const ICData& ic_data = *call->ic_data(); |
| - Definition* d2i_instr = NULL; |
| - if (ic_data.deopt_reason() == kDeoptDoubleToSmi) { |
| - // Do not repeatedly deoptimize because result didn't fit into Smi. |
| - d2i_instr = new DoubleToIntegerInstr(call->ArgumentAt(0)->value(), |
| - call); |
| - } else { |
| - // Optimistically assume result fits into Smi. |
| - d2i_instr = new DoubleToSmiInstr(call->ArgumentAt(0)->value(), call); |
| + switch (recognized_kind) { |
| + case MethodRecognizer::kDoubleToInteger: { |
| + AddCheckClass(call, call->ArgumentAt(0)->value()->Copy()); |
| + ASSERT(call->HasICData()); |
| + const ICData& ic_data = *call->ic_data(); |
| + Definition* d2i_instr = NULL; |
| + if (ic_data.deopt_reason() == kDeoptDoubleToSmi) { |
| + // Do not repeatedly deoptimize because result didn't fit into Smi. |
| + d2i_instr = new DoubleToIntegerInstr(call->ArgumentAt(0)->value(), |
| + call); |
| + } else { |
| + // Optimistically assume result fits into Smi. |
| + d2i_instr = new DoubleToSmiInstr(call->ArgumentAt(0)->value(), call); |
| + } |
| + call->ReplaceWith(d2i_instr, current_iterator()); |
| + RemovePushArguments(call); |
| + return true; |
| } |
| - call->ReplaceWith(d2i_instr, current_iterator()); |
| - RemovePushArguments(call); |
| - return true; |
| - } |
| - if ((recognized_kind == MethodRecognizer::kDoubleTruncate) || |
| - (recognized_kind == MethodRecognizer::kDoubleRound) || |
| - (recognized_kind == MethodRecognizer::kDoubleFloor) || |
| - (recognized_kind == MethodRecognizer::kDoubleCeil)) { |
| - if (!CPUFeatures::double_truncate_round_supported()) { |
| - return false; |
| + case MethodRecognizer::kDoublePow: { |
| + ReplaceWithMathCFunction(call, recognized_kind); |
| + return true; |
| } |
| - AddCheckClass(call, call->ArgumentAt(0)->value()->Copy()); |
| - DoubleToDoubleInstr* d2d_instr = |
| - new DoubleToDoubleInstr(call->ArgumentAt(0)->value(), |
| - call, |
| - recognized_kind); |
| - call->ReplaceWith(d2d_instr, current_iterator()); |
| - RemovePushArguments(call); |
| - return true; |
| + case MethodRecognizer::kDoubleTruncate: |
| + case MethodRecognizer::kDoubleRound: |
| + case MethodRecognizer::kDoubleFloor: |
| + case MethodRecognizer::kDoubleCeil: { |
| + if (!CPUFeatures::double_truncate_round_supported()) { |
| + ReplaceWithMathCFunction(call, recognized_kind); |
| + } else { |
| + AddCheckClass(call, call->ArgumentAt(0)->value()->Copy()); |
| + DoubleToDoubleInstr* d2d_instr = |
| + new DoubleToDoubleInstr(call->ArgumentAt(0)->value(), |
| + call, |
| + recognized_kind); |
| + call->ReplaceWith(d2d_instr, current_iterator()); |
| + RemovePushArguments(call); |
| + } |
| + return true; |
| + } |
|
Florian Schneider
2013/01/21 16:31:26
I'd add a comment for intended fall-through.
Vyacheslav Egorov (Google)
2013/01/21 16:50:08
There is no fall through. Removed curly braces for
|
| + default: |
| + // Unsupported method. |
| + return false; |
| } |
| } |
| @@ -4335,6 +4361,12 @@ void ConstantPropagator::VisitDoubleToDouble(DoubleToDoubleInstr* instr) { |
| } |
| +void ConstantPropagator::VisitInvokeMathCFunction( |
| + InvokeMathCFunctionInstr* instr) { |
| + // TODO(kmillikin): Handle conversion. |
| + SetValue(instr, non_constant_); |
| +} |
| + |
| void ConstantPropagator::VisitConstant(ConstantInstr* instr) { |
| SetValue(instr, instr->value()); |
| } |