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 d37e602917adcb0bda97841c7f942800996b6ded..8e108ba32d35c256a1245a46b2cf2148c769963d 100644 |
| --- a/runtime/vm/flow_graph_optimizer.cc |
| +++ b/runtime/vm/flow_graph_optimizer.cc |
| @@ -547,6 +547,10 @@ static bool HasOnlyTwoFloat32x4s(const ICData& ic_data) { |
| ICDataHasReceiverArgumentClassIds(ic_data, kFloat32x4Cid, kFloat32x4Cid); |
| } |
| +static bool HasOnlyTwoUint32x4s(const ICData& ic_data) { |
| + return (ic_data.NumberOfChecks() == 1) && |
| + ICDataHasReceiverArgumentClassIds(ic_data, kUint32x4Cid, kUint32x4Cid); |
| +} |
| // Returns false if the ICData contains anything other than the 4 combinations |
| // of Mint and Smi for the receiver and argument classes. |
| @@ -1025,6 +1029,8 @@ bool FlowGraphOptimizer::TryReplaceWithBinaryOp(InstanceCallInstr* call, |
| operands_type = kSmiCid; |
| } else if (HasTwoMintOrSmi(ic_data)) { |
| operands_type = kMintCid; |
| + } else if (HasOnlyTwoUint32x4s(ic_data)) { |
| + operands_type = kUint32x4Cid; |
| } else { |
| return false; |
| } |
| @@ -1113,6 +1119,26 @@ bool FlowGraphOptimizer::TryReplaceWithBinaryOp(InstanceCallInstr* call, |
| new BinaryFloat32x4OpInstr(op_kind, new Value(left), new Value(right), |
| call); |
| ReplaceCall(call, float32x4_bin_op); |
| + } else if (operands_type == kUint32x4Cid) { |
| + // 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. |
| + BinaryUint32x4OpInstr* uint32x4_bin_op = |
| + new BinaryUint32x4OpInstr(op_kind, new Value(left), new Value(right), |
| + call); |
| + ReplaceCall(call, uint32x4_bin_op); |
| } else if (op_kind == Token::kMOD) { |
| // TODO(vegorov): implement fast path code for modulo. |
| ASSERT(operands_type == kSmiCid); |
| @@ -1487,6 +1513,16 @@ bool FlowGraphOptimizer::TryInlineInstanceGetter(InstanceCallInstr* call) { |
| return false; |
| } |
| return InlineFloat32x4Getter(call, recognized_kind); |
| + case MethodRecognizer::kUint32x4GetFlagX: |
| + case MethodRecognizer::kUint32x4GetFlagY: |
| + case MethodRecognizer::kUint32x4GetFlagZ: |
| + case MethodRecognizer::kUint32x4GetFlagW: { |
| + if (!ic_data.HasReceiverClassId(kUint32x4Cid) || |
|
srdjan
2013/05/10 18:36:58
Bad indent (3 instead of 2)
Cutch
2013/05/13 19:40:24
Done.
|
| + !ic_data.HasOneTarget()) { |
| + return false; |
| + } |
| + return false; |
|
Florian Schneider
2013/05/13 08:46:20
dbc: Shouldn't this return a Uint32x4GetFlagInstr
Cutch
2013/05/13 19:40:24
Done.
|
| + } |
| default: |
| ASSERT(recognized_kind == MethodRecognizer::kUnknown); |
| } |
| @@ -1754,6 +1790,10 @@ bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { |
| if ((class_ids[0] == kFloat32x4Cid) && (ic_data.NumberOfChecks() == 1)) { |
| return TryInlineFloat32x4Method(call, recognized_kind); |
| } |
| + |
| + if ((class_ids[0] == kUint32x4Cid) && (ic_data.NumberOfChecks() == 1)) { |
| + return TryInlineUint32x4Method(call, recognized_kind); |
| + } |
| return false; |
| } |
| @@ -1909,6 +1949,70 @@ bool FlowGraphOptimizer::TryInlineFloat32x4Method( |
| } |
| +bool FlowGraphOptimizer::TryInlineUint32x4Method( |
| + InstanceCallInstr* call, |
| + MethodRecognizer::Kind recognized_kind) { |
| + ASSERT(call->HasICData()); |
| + switch (recognized_kind) { |
| + case MethodRecognizer::kUint32x4Select: { |
| + Definition* mask = call->ArgumentAt(0); |
| + Definition* trueValue = call->ArgumentAt(1); |
| + Definition* falseValue = call->ArgumentAt(2); |
| + // Type check left. |
| + AddCheckClass(mask, |
| + ICData::ZoneHandle( |
| + call->ic_data()->AsUnaryClassChecksForArgNr(0)), |
| + call->deopt_id(), |
| + call->env(), |
| + call); |
| + Uint32x4SelectInstr* select = new Uint32x4SelectInstr( |
| + new Value(mask), |
| + new Value(trueValue), |
| + new Value(falseValue), |
| + call); |
| + ReplaceCall(call, select); |
| + return true; |
| + } |
| + case MethodRecognizer::kUint32x4ToUint32x4: { |
| + Definition* left = call->ArgumentAt(0); |
| + // Type check left. |
| + AddCheckClass(left, |
| + ICData::ZoneHandle( |
| + call->ic_data()->AsUnaryClassChecksForArgNr(0)), |
| + call->deopt_id(), |
| + call->env(), |
| + call); |
| + Uint32x4ToFloat32x4Instr* cast = |
| + new Uint32x4ToFloat32x4Instr(new Value(left), call); |
| + ReplaceCall(call, cast); |
| + return true; |
| + } |
| + case MethodRecognizer::kUint32x4WithFlagX: |
| + case MethodRecognizer::kUint32x4WithFlagY: |
| + case MethodRecognizer::kUint32x4WithFlagZ: |
| + case MethodRecognizer::kUint32x4WithFlagW: { |
| + Definition* left = call->ArgumentAt(0); |
| + Definition* flag = call->ArgumentAt(1); |
| + // Type check left. |
| + AddCheckClass(left, |
| + ICData::ZoneHandle( |
| + call->ic_data()->AsUnaryClassChecksForArgNr(0)), |
| + call->deopt_id(), |
| + call->env(), |
| + call); |
| + Uint32x4SetFlagInstr* setFlag = new Uint32x4SetFlagInstr(recognized_kind, |
| + new Value(left), |
| + new Value(flag), |
| + call); |
| + ReplaceCall(call, setFlag); |
| + return true; |
| + } |
| + default: |
| + return false; |
| + } |
| +} |
| + |
| + |
| bool FlowGraphOptimizer::BuildByteArrayViewLoad( |
| InstanceCallInstr* call, |
| intptr_t receiver_cid, |
| @@ -2302,6 +2406,14 @@ void FlowGraphOptimizer::VisitStaticCall(StaticCallInstr* call) { |
| new Value(call->ArgumentAt(4)), |
| call); |
| ReplaceCall(call, con); |
| + } else if (recognized_kind == MethodRecognizer::kUint32x4BoolConstructor) { |
| + Uint32x4BoolConstructorInstr* con = new Uint32x4BoolConstructorInstr( |
| + new Value(call->ArgumentAt(1)), |
| + new Value(call->ArgumentAt(2)), |
| + new Value(call->ArgumentAt(3)), |
| + new Value(call->ArgumentAt(4)), |
| + call); |
|
srdjan
2013/05/10 18:36:58
Indent 4 spaces
|
| + ReplaceCall(call, con); |
| } |
| } |
| @@ -5259,6 +5371,38 @@ void ConstantPropagator::VisitFloat32x4ToUint32x4( |
| } |
| +void ConstantPropagator::VisitUint32x4BoolConstructor( |
| + Uint32x4BoolConstructorInstr* instr) { |
| + SetValue(instr, non_constant_); |
| +} |
| + |
| + |
| +void ConstantPropagator::VisitUint32x4GetFlag(Uint32x4GetFlagInstr* instr) { |
| + SetValue(instr, non_constant_); |
| +} |
| + |
| + |
| +void ConstantPropagator::VisitUint32x4SetFlag(Uint32x4SetFlagInstr* instr) { |
| + SetValue(instr, non_constant_); |
| +} |
| + |
| + |
| +void ConstantPropagator::VisitUint32x4Select(Uint32x4SelectInstr* instr) { |
| + SetValue(instr, non_constant_); |
| +} |
| + |
| + |
| +void ConstantPropagator::VisitUint32x4ToFloat32x4( |
| + Uint32x4ToFloat32x4Instr* instr) { |
| + SetValue(instr, non_constant_); |
| +} |
| + |
| + |
| +void ConstantPropagator::VisitBinaryUint32x4Op(BinaryUint32x4OpInstr* instr) { |
| + SetValue(instr, non_constant_); |
| +} |
| + |
| + |
| void ConstantPropagator::VisitMathSqrt(MathSqrtInstr* instr) { |
| const Object& value = instr->value()->definition()->constant_value(); |
| if (IsNonConstant(value)) { |