| Index: runtime/vm/flow_graph_optimizer.cc
|
| ===================================================================
|
| --- runtime/vm/flow_graph_optimizer.cc (revision 39445)
|
| +++ runtime/vm/flow_graph_optimizer.cc (working copy)
|
| @@ -1560,6 +1560,14 @@
|
| return InlineStringCodeUnitAt(call, receiver_cid, entry, last);
|
| case MethodRecognizer::kStringBaseCharAt:
|
| return InlineStringBaseCharAt(call, receiver_cid, entry, last);
|
| + case MethodRecognizer::kDoubleAdd:
|
| + return InlineDoubleOp(Token::kADD, call, entry, last);
|
| + case MethodRecognizer::kDoubleSub:
|
| + return InlineDoubleOp(Token::kSUB, call, entry, last);
|
| + case MethodRecognizer::kDoubleMul:
|
| + return InlineDoubleOp(Token::kMUL, call, entry, last);
|
| + case MethodRecognizer::kDoubleDiv:
|
| + return InlineDoubleOp(Token::kDIV, call, entry, last);
|
| default:
|
| return false;
|
| }
|
| @@ -2336,21 +2344,6 @@
|
| }
|
|
|
|
|
| -LoadFieldInstr* FlowGraphOptimizer::BuildLoadStringLength(Definition* str) {
|
| - // Treat length loads as mutable (i.e. affected by side effects) to avoid
|
| - // hoisting them since we can't hoist the preceding class-check. This
|
| - // is because of externalization of strings that affects their class-id.
|
| - LoadFieldInstr* load = new(I) LoadFieldInstr(
|
| - new(I) Value(str),
|
| - String::length_offset(),
|
| - Type::ZoneHandle(I, Type::SmiType()),
|
| - str->token_pos());
|
| - load->set_result_cid(kSmiCid);
|
| - load->set_recognized_kind(MethodRecognizer::kStringBaseLength);
|
| - return load;
|
| -}
|
| -
|
| -
|
| bool FlowGraphOptimizer::InlineFloat32x4Getter(InstanceCallInstr* call,
|
| MethodRecognizer::Kind getter) {
|
| if (!ShouldInlineSimd()) {
|
| @@ -2711,7 +2704,17 @@
|
| FlowGraph::kEffect);
|
|
|
| // Load the length of the string.
|
| - LoadFieldInstr* length = BuildLoadStringLength(str);
|
| + // Treat length loads as mutable (i.e. affected by side effects) to avoid
|
| + // hoisting them since we can't hoist the preceding class-check. This
|
| + // is because of externalization of strings that affects their class-id.
|
| + LoadFieldInstr* length = new(I) LoadFieldInstr(
|
| + new(I) Value(str),
|
| + String::length_offset(),
|
| + Type::ZoneHandle(I, Type::SmiType()),
|
| + str->token_pos());
|
| + length->set_result_cid(kSmiCid);
|
| + length->set_recognized_kind(MethodRecognizer::kStringBaseLength);
|
| +
|
| cursor = flow_graph()->AppendTo(cursor, length, NULL, FlowGraph::kValue);
|
| // Bounds check.
|
| cursor = flow_graph()->AppendTo(cursor,
|
| @@ -2790,6 +2793,30 @@
|
| }
|
|
|
|
|
| +bool FlowGraphOptimizer::InlineDoubleOp(
|
| + Token::Kind op_kind,
|
| + Instruction* call,
|
| + TargetEntryInstr** entry,
|
| + Definition** last) {
|
| + Definition* left = call->ArgumentAt(0);
|
| + Definition* right = call->ArgumentAt(1);
|
| +
|
| + *entry = new(I) TargetEntryInstr(flow_graph()->allocate_block_id(),
|
| + call->GetBlock()->try_index());
|
| + (*entry)->InheritDeoptTarget(I, call);
|
| + // Arguments are checked. No need for class check.
|
| + BinaryDoubleOpInstr* double_bin_op =
|
| + new(I) BinaryDoubleOpInstr(op_kind,
|
| + new(I) Value(left),
|
| + new(I) Value(right),
|
| + call->deopt_id(), call->token_pos());
|
| + flow_graph()->AppendTo(*entry, double_bin_op, call->env(), FlowGraph::kValue);
|
| + *last = double_bin_op;
|
| +
|
| + return true;
|
| +}
|
| +
|
| +
|
| void FlowGraphOptimizer::ReplaceWithMathCFunction(
|
| InstanceCallInstr* call,
|
| MethodRecognizer::Kind recognized_kind) {
|
| @@ -2960,6 +2987,11 @@
|
| ReplaceCall(call, d2d_instr);
|
| }
|
| return true;
|
| + case MethodRecognizer::kDoubleAdd:
|
| + case MethodRecognizer::kDoubleSub:
|
| + case MethodRecognizer::kDoubleMul:
|
| + case MethodRecognizer::kDoubleDiv:
|
| + return TryReplaceInstanceCallWithInline(call);
|
| default:
|
| // Unsupported method.
|
| return false;
|
| @@ -4342,6 +4374,23 @@
|
| CreateArrayInstr* create_array =
|
| new(I) CreateArrayInstr(call->token_pos(), type, num_elements);
|
| ReplaceCall(call, create_array);
|
| + } 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()));
|
| + }
|
| + }
|
| } else if (call->function().IsFactory()) {
|
| const Class& function_class =
|
| Class::Handle(I, call->function().Owner());
|
|
|