| Index: runtime/vm/flow_graph_optimizer.cc
|
| diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
|
| index 8833ac305ece4a6b6142de01cbd087c395f6006d..d472575b40e1fe628e6edecdcded5cf7c0202320 100644
|
| --- a/runtime/vm/flow_graph_optimizer.cc
|
| +++ b/runtime/vm/flow_graph_optimizer.cc
|
| @@ -531,6 +531,11 @@ static bool HasOnlyTwoSmis(const ICData& ic_data) {
|
| ICDataHasReceiverArgumentClassIds(ic_data, kSmiCid, kSmiCid);
|
| }
|
|
|
| +static bool HasOnlyTwoFloat32x4s(const ICData& ic_data) {
|
| + return (ic_data.NumberOfChecks() == 1) &&
|
| + ICDataHasReceiverArgumentClassIds(ic_data, kFloat32x4Cid, kFloat32x4Cid);
|
| +}
|
| +
|
|
|
| // Returns false if the ICData contains anything other than the 4 combinations
|
| // of Mint and Smi for the receiver and argument classes.
|
| @@ -965,6 +970,8 @@ bool FlowGraphOptimizer::TryReplaceWithBinaryOp(InstanceCallInstr* call,
|
| operands_type = kMintCid;
|
| } else if (ShouldSpecializeForDouble(ic_data)) {
|
| operands_type = kDoubleCid;
|
| + } else if (HasOnlyTwoFloat32x4s(ic_data)) {
|
| + operands_type = kFloat32x4Cid;
|
| } else {
|
| return false;
|
| }
|
| @@ -978,6 +985,8 @@ bool FlowGraphOptimizer::TryReplaceWithBinaryOp(InstanceCallInstr* call,
|
| operands_type = kSmiCid;
|
| } else if (ShouldSpecializeForDouble(ic_data)) {
|
| operands_type = kDoubleCid;
|
| + } else if (HasOnlyTwoFloat32x4s(ic_data)) {
|
| + operands_type = kFloat32x4Cid;
|
| } else {
|
| return false;
|
| }
|
| @@ -985,6 +994,8 @@ bool FlowGraphOptimizer::TryReplaceWithBinaryOp(InstanceCallInstr* call,
|
| case Token::kDIV:
|
| if (ShouldSpecializeForDouble(ic_data)) {
|
| operands_type = kDoubleCid;
|
| + } else if (HasOnlyTwoFloat32x4s(ic_data)) {
|
| + operands_type = kFloat32x4Cid;
|
| } else {
|
| return false;
|
| }
|
| @@ -1071,6 +1082,26 @@ bool FlowGraphOptimizer::TryReplaceWithBinaryOp(InstanceCallInstr* call,
|
| call);
|
| ReplaceCall(call, bin_op);
|
| }
|
| + } else if (operands_type == kFloat32x4Cid) {
|
| + // Type check left.
|
| + AddCheckClass(left,
|
| + ICData::ZoneHandle(
|
| + call->ic_data()->AsUnaryClassChecksForArgNr(0)),
|
| + call->deopt_id(),
|
| + call->env(),
|
| + call);
|
| + // Type check right.
|
| + AddCheckClass(right,
|
| + ICData::ZoneHandle(
|
| + call->ic_data()->AsUnaryClassChecksForArgNr(1)),
|
| + call->deopt_id(),
|
| + call->env(),
|
| + call);
|
| + // Replace call.
|
| + BinaryFloat32x4OpInstr* float32x4_bin_op =
|
| + new BinaryFloat32x4OpInstr(op_kind, new Value(left), new Value(right),
|
| + call);
|
| + ReplaceCall(call, float32x4_bin_op);
|
| } else if (op_kind == Token::kMOD) {
|
| // TODO(vegorov): implement fast path code for modulo.
|
| ASSERT(operands_type == kSmiCid);
|
| @@ -4399,6 +4430,19 @@ void ConstantPropagator::VisitBinaryDoubleOp(
|
| }
|
|
|
|
|
| +void ConstantPropagator::VisitBinaryFloat32x4Op(
|
| + BinaryFloat32x4OpInstr* instr) {
|
| + const Object& left = instr->left()->definition()->constant_value();
|
| + const Object& right = instr->right()->definition()->constant_value();
|
| + if (IsNonConstant(left) || IsNonConstant(right)) {
|
| + SetValue(instr, non_constant_);
|
| + } else if (IsConstant(left) && IsConstant(right)) {
|
| + // TODO(kmillikin): Handle binary operation.
|
| + SetValue(instr, non_constant_);
|
| + }
|
| +}
|
| +
|
| +
|
| void ConstantPropagator::VisitMathSqrt(MathSqrtInstr* instr) {
|
| const Object& value = instr->value()->definition()->constant_value();
|
| if (IsNonConstant(value)) {
|
|
|