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)) { |