Index: runtime/vm/flow_graph_optimizer.cc |
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc |
index 2c384794d5e643003fdeca29f07b4df069b31d3d..cda4032860b2d243bccc1e8454dd3b3dc1ddedc6 100644 |
--- a/runtime/vm/flow_graph_optimizer.cc |
+++ b/runtime/vm/flow_graph_optimizer.cc |
@@ -1692,24 +1692,30 @@ bool FlowGraphOptimizer::InlineFloat32x4Getter(InstanceCallInstr* call, |
call->env(), |
call); |
intptr_t mask = 0; |
- if (getter == MethodRecognizer::kFloat32x4Shuffle) { |
+ if ((getter == MethodRecognizer::kFloat32x4Shuffle) || |
+ (getter == MethodRecognizer::kFloat32x4ShuffleMix)) { |
// Extract shuffle mask. |
- ASSERT(call->ArgumentCount() == 2); |
- Definition* mask_definition = call->ArgumentAt(1); |
+ Definition* mask_definition = NULL; |
+ if (getter == MethodRecognizer::kFloat32x4Shuffle) { |
+ ASSERT(call->ArgumentCount() == 2); |
+ mask_definition = call->ArgumentAt(1); |
+ } else { |
+ ASSERT(getter == MethodRecognizer::kFloat32x4ShuffleMix); |
+ ASSERT(call->ArgumentCount() == 3); |
+ mask_definition = call->ArgumentAt(2); |
+ } |
if (!mask_definition->IsConstant()) { |
- // Not a constant. |
return false; |
} |
ASSERT(mask_definition->IsConstant()); |
ConstantInstr* constant_instruction = mask_definition->AsConstant(); |
const Object& constant_mask = constant_instruction->value(); |
if (!constant_mask.IsSmi()) { |
- // Not a smi. |
return false; |
} |
ASSERT(constant_mask.IsSmi()); |
mask = Smi::Cast(constant_mask).Value(); |
- if (mask < 0 || mask > 255) { |
+ if ((mask < 0) || (mask > 255)) { |
// Not a valid mask. |
return false; |
} |
@@ -1721,13 +1727,22 @@ bool FlowGraphOptimizer::InlineFloat32x4Getter(InstanceCallInstr* call, |
call->deopt_id()); |
ReplaceCall(call, instr); |
return true; |
+ } else if (getter == MethodRecognizer::kFloat32x4ShuffleMix) { |
+ Simd32x4ShuffleMixInstr* instr = new Simd32x4ShuffleMixInstr( |
+ getter, |
+ new Value(call->ArgumentAt(0)), |
+ new Value(call->ArgumentAt(1)), |
+ mask, |
+ call->deopt_id()); |
+ ReplaceCall(call, instr); |
+ return true; |
} else { |
ASSERT((getter == MethodRecognizer::kFloat32x4Shuffle) || |
(getter == MethodRecognizer::kFloat32x4ShuffleX) || |
(getter == MethodRecognizer::kFloat32x4ShuffleY) || |
(getter == MethodRecognizer::kFloat32x4ShuffleZ) || |
(getter == MethodRecognizer::kFloat32x4ShuffleW)); |
- Float32x4ShuffleInstr* instr = new Float32x4ShuffleInstr( |
+ Simd32x4ShuffleInstr* instr = new Simd32x4ShuffleInstr( |
getter, |
new Value(call->ArgumentAt(0)), |
mask, |
@@ -1751,6 +1766,35 @@ bool FlowGraphOptimizer::InlineUint32x4Getter(InstanceCallInstr* call, |
call->deopt_id(), |
call->env(), |
call); |
+ intptr_t mask = 0; |
+ if ((getter == MethodRecognizer::kUint32x4Shuffle) || |
+ (getter == MethodRecognizer::kUint32x4ShuffleMix)) { |
+ // Extract shuffle mask. |
+ Definition* mask_definition = NULL; |
+ if (getter == MethodRecognizer::kUint32x4Shuffle) { |
+ ASSERT(call->ArgumentCount() == 2); |
+ mask_definition = call->ArgumentAt(1); |
+ } else { |
+ ASSERT(getter == MethodRecognizer::kUint32x4ShuffleMix); |
+ ASSERT(call->ArgumentCount() == 3); |
+ mask_definition = call->ArgumentAt(2); |
+ } |
+ if (!mask_definition->IsConstant()) { |
+ return false; |
+ } |
+ ASSERT(mask_definition->IsConstant()); |
+ ConstantInstr* constant_instruction = mask_definition->AsConstant(); |
+ const Object& constant_mask = constant_instruction->value(); |
+ if (!constant_mask.IsSmi()) { |
+ return false; |
+ } |
+ ASSERT(constant_mask.IsSmi()); |
+ mask = Smi::Cast(constant_mask).Value(); |
+ if ((mask < 0) || (mask > 255)) { |
+ // Not a valid mask. |
+ return false; |
+ } |
+ } |
if (getter == MethodRecognizer::kUint32x4GetSignMask) { |
Simd32x4GetSignMaskInstr* instr = new Simd32x4GetSignMaskInstr( |
getter, |
@@ -1758,6 +1802,23 @@ bool FlowGraphOptimizer::InlineUint32x4Getter(InstanceCallInstr* call, |
call->deopt_id()); |
ReplaceCall(call, instr); |
return true; |
+ } else if (getter == MethodRecognizer::kUint32x4ShuffleMix) { |
+ Simd32x4ShuffleMixInstr* instr = new Simd32x4ShuffleMixInstr( |
+ getter, |
+ new Value(call->ArgumentAt(0)), |
+ new Value(call->ArgumentAt(1)), |
+ mask, |
+ call->deopt_id()); |
+ ReplaceCall(call, instr); |
+ return true; |
+ } else if (getter == MethodRecognizer::kUint32x4Shuffle) { |
+ Simd32x4ShuffleInstr* instr = new Simd32x4ShuffleInstr( |
+ getter, |
+ new Value(call->ArgumentAt(0)), |
+ mask, |
+ call->deopt_id()); |
+ ReplaceCall(call, instr); |
+ return true; |
} else { |
Uint32x4GetFlagInstr* instr = new Uint32x4GetFlagInstr( |
getter, |
@@ -2320,26 +2381,6 @@ bool FlowGraphOptimizer::TryInlineFloat32x4Method( |
ReplaceCall(call, minmax); |
return true; |
} |
- case MethodRecognizer::kFloat32x4WithZWInXY: |
- case MethodRecognizer::kFloat32x4InterleaveXY: |
- case MethodRecognizer::kFloat32x4InterleaveZW: |
- case MethodRecognizer::kFloat32x4InterleaveXYPairs: |
- case MethodRecognizer::kFloat32x4InterleaveZWPairs: { |
- Definition* left = call->ArgumentAt(0); |
- Definition* right = call->ArgumentAt(1); |
- // Type check left. |
- AddCheckClass(left, |
- ICData::ZoneHandle( |
- call->ic_data()->AsUnaryClassChecksForArgNr(0)), |
- call->deopt_id(), |
- call->env(), |
- call); |
- Float32x4TwoArgShuffleInstr* two_arg_shuffle = |
- new Float32x4TwoArgShuffleInstr(recognized_kind, new Value(left), |
- new Value(right), call->deopt_id()); |
- ReplaceCall(call, two_arg_shuffle); |
- return true; |
- } |
case MethodRecognizer::kFloat32x4Scale: { |
Definition* left = call->ArgumentAt(0); |
Definition* right = call->ArgumentAt(1); |
@@ -2429,6 +2470,7 @@ bool FlowGraphOptimizer::TryInlineFloat32x4Method( |
ReplaceCall(call, clamp); |
return true; |
} |
+ case MethodRecognizer::kFloat32x4ShuffleMix: |
case MethodRecognizer::kFloat32x4Shuffle: { |
return InlineFloat32x4Getter(call, recognized_kind); |
} |
@@ -2446,6 +2488,8 @@ bool FlowGraphOptimizer::TryInlineUint32x4Method( |
} |
ASSERT(call->HasICData()); |
switch (recognized_kind) { |
+ case MethodRecognizer::kUint32x4ShuffleMix: |
+ case MethodRecognizer::kUint32x4Shuffle: |
case MethodRecognizer::kUint32x4GetFlagX: |
case MethodRecognizer::kUint32x4GetFlagY: |
case MethodRecognizer::kUint32x4GetFlagZ: |
@@ -6885,7 +6929,13 @@ void ConstantPropagator::VisitFloat32x4Constructor( |
} |
-void ConstantPropagator::VisitFloat32x4Shuffle(Float32x4ShuffleInstr* instr) { |
+void ConstantPropagator::VisitSimd32x4Shuffle(Simd32x4ShuffleInstr* instr) { |
+ SetValue(instr, non_constant_); |
+} |
+ |
+ |
+void ConstantPropagator::VisitSimd32x4ShuffleMix( |
+ Simd32x4ShuffleMixInstr* instr) { |
SetValue(instr, non_constant_); |
} |
@@ -6948,12 +6998,6 @@ void ConstantPropagator::VisitFloat32x4ToUint32x4( |
} |
-void ConstantPropagator::VisitFloat32x4TwoArgShuffle( |
- Float32x4TwoArgShuffleInstr* instr) { |
- SetValue(instr, non_constant_); |
-} |
- |
- |
void ConstantPropagator::VisitUint32x4BoolConstructor( |
Uint32x4BoolConstructorInstr* instr) { |
SetValue(instr, non_constant_); |