Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(974)

Unified Diff: runtime/vm/jit_optimizer.cc

Issue 2254053002: Move inlining of recognized SIMD methods to the flow-graph inliner. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: add missing guard for speculative inlining Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« runtime/vm/flow_graph_inliner.cc ('K') | « runtime/vm/jit_optimizer.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/jit_optimizer.cc
diff --git a/runtime/vm/jit_optimizer.cc b/runtime/vm/jit_optimizer.cc
index 56074a2ebda735139356b64012f7fee09ba4206e..49e5cd990ad60b0bd63cb321d963d880f6490fb1 100644
--- a/runtime/vm/jit_optimizer.cc
+++ b/runtime/vm/jit_optimizer.cc
@@ -1338,81 +1338,6 @@ bool JitOptimizer::InlineImplicitInstanceGetter(InstanceCallInstr* call) {
}
-bool JitOptimizer::InlineFloat32x4Getter(InstanceCallInstr* call,
- MethodRecognizer::Kind getter) {
- if (!ShouldInlineSimd()) {
- return false;
- }
- AddCheckClass(call->ArgumentAt(0),
- ICData::ZoneHandle(
- Z, call->ic_data()->AsUnaryClassChecksForArgNr(0)),
- call->deopt_id(),
- call->env(),
- call);
- intptr_t mask = 0;
- if ((getter == MethodRecognizer::kFloat32x4Shuffle) ||
- (getter == MethodRecognizer::kFloat32x4ShuffleMix)) {
- // Extract shuffle mask.
- 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()) {
- 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::kFloat32x4GetSignMask) {
- Simd32x4GetSignMaskInstr* instr = new(Z) Simd32x4GetSignMaskInstr(
- getter,
- new(Z) Value(call->ArgumentAt(0)),
- call->deopt_id());
- ReplaceCall(call, instr);
- return true;
- } else if (getter == MethodRecognizer::kFloat32x4ShuffleMix) {
- Simd32x4ShuffleMixInstr* instr = new(Z) Simd32x4ShuffleMixInstr(
- getter,
- new(Z) Value(call->ArgumentAt(0)),
- new(Z) 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));
- Simd32x4ShuffleInstr* instr = new(Z) Simd32x4ShuffleInstr(
- getter,
- new(Z) Value(call->ArgumentAt(0)),
- mask,
- call->deopt_id());
- ReplaceCall(call, instr);
- return true;
- }
- UNREACHABLE();
- return false;
-}
-
-
bool JitOptimizer::InlineFloat64x2Getter(InstanceCallInstr* call,
MethodRecognizer::Kind getter) {
if (!ShouldInlineSimd()) {
@@ -1439,81 +1364,6 @@ bool JitOptimizer::InlineFloat64x2Getter(InstanceCallInstr* call,
}
-bool JitOptimizer::InlineInt32x4Getter(InstanceCallInstr* call,
- MethodRecognizer::Kind getter) {
- if (!ShouldInlineSimd()) {
- return false;
- }
- AddCheckClass(call->ArgumentAt(0),
- ICData::ZoneHandle(
- Z, call->ic_data()->AsUnaryClassChecksForArgNr(0)),
- call->deopt_id(),
- call->env(),
- call);
- intptr_t mask = 0;
- if ((getter == MethodRecognizer::kInt32x4Shuffle) ||
- (getter == MethodRecognizer::kInt32x4ShuffleMix)) {
- // Extract shuffle mask.
- Definition* mask_definition = NULL;
- if (getter == MethodRecognizer::kInt32x4Shuffle) {
- ASSERT(call->ArgumentCount() == 2);
- mask_definition = call->ArgumentAt(1);
- } else {
- ASSERT(getter == MethodRecognizer::kInt32x4ShuffleMix);
- 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::kInt32x4GetSignMask) {
- Simd32x4GetSignMaskInstr* instr = new(Z) Simd32x4GetSignMaskInstr(
- getter,
- new(Z) Value(call->ArgumentAt(0)),
- call->deopt_id());
- ReplaceCall(call, instr);
- return true;
- } else if (getter == MethodRecognizer::kInt32x4ShuffleMix) {
- Simd32x4ShuffleMixInstr* instr = new(Z) Simd32x4ShuffleMixInstr(
- getter,
- new(Z) Value(call->ArgumentAt(0)),
- new(Z) Value(call->ArgumentAt(1)),
- mask,
- call->deopt_id());
- ReplaceCall(call, instr);
- return true;
- } else if (getter == MethodRecognizer::kInt32x4Shuffle) {
- Simd32x4ShuffleInstr* instr = new(Z) Simd32x4ShuffleInstr(
- getter,
- new(Z) Value(call->ArgumentAt(0)),
- mask,
- call->deopt_id());
- ReplaceCall(call, instr);
- return true;
- } else {
- Int32x4GetFlagInstr* instr = new(Z) Int32x4GetFlagInstr(
- getter,
- new(Z) Value(call->ArgumentAt(0)),
- call->deopt_id());
- ReplaceCall(call, instr);
- return true;
- }
-}
-
-
bool JitOptimizer::InlineFloat32x4BinaryOp(InstanceCallInstr* call,
Token::Kind op_kind) {
if (!ShouldInlineSimd()) {
@@ -1803,367 +1653,18 @@ bool JitOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) {
}
}
- if (IsSupportedByteArrayViewCid(class_ids[0])) {
+ if (IsSupportedByteArrayViewCid(class_ids[0]) ||
+ (class_ids[0] == kFloat32x4Cid) ||
+ (class_ids[0] == kInt32x4Cid) ||
+ (class_ids[0] == kFloat64x2Cid)) {
return FlowGraphInliner::TryReplaceInstanceCallWithInline(
flow_graph_, current_iterator(), call);
}
- if (class_ids[0] == kFloat32x4Cid) {
- return TryInlineFloat32x4Method(call, recognized_kind);
- }
-
- if (class_ids[0] == kInt32x4Cid) {
- return TryInlineInt32x4Method(call, recognized_kind);
- }
-
- if (class_ids[0] == kFloat64x2Cid) {
- return TryInlineFloat64x2Method(call, recognized_kind);
- }
-
- return false;
-}
-
-
-bool JitOptimizer::TryInlineFloat32x4Constructor(
- StaticCallInstr* call,
- MethodRecognizer::Kind recognized_kind) {
- if (!ShouldInlineSimd()) {
- return false;
- }
- if (recognized_kind == MethodRecognizer::kFloat32x4Zero) {
- Float32x4ZeroInstr* zero = new(Z) Float32x4ZeroInstr();
- ReplaceCall(call, zero);
- return true;
- } else if (recognized_kind == MethodRecognizer::kFloat32x4Splat) {
- Float32x4SplatInstr* splat =
- new(Z) Float32x4SplatInstr(
- new(Z) Value(call->ArgumentAt(1)), call->deopt_id());
- ReplaceCall(call, splat);
- return true;
- } else if (recognized_kind == MethodRecognizer::kFloat32x4Constructor) {
- Float32x4ConstructorInstr* con =
- new(Z) Float32x4ConstructorInstr(
- new(Z) Value(call->ArgumentAt(1)),
- new(Z) Value(call->ArgumentAt(2)),
- new(Z) Value(call->ArgumentAt(3)),
- new(Z) Value(call->ArgumentAt(4)),
- call->deopt_id());
- ReplaceCall(call, con);
- return true;
- } else if (recognized_kind == MethodRecognizer::kFloat32x4FromInt32x4Bits) {
- Int32x4ToFloat32x4Instr* cast =
- new(Z) Int32x4ToFloat32x4Instr(
- new(Z) Value(call->ArgumentAt(1)), call->deopt_id());
- ReplaceCall(call, cast);
- return true;
- } else if (recognized_kind == MethodRecognizer::kFloat32x4FromFloat64x2) {
- Float64x2ToFloat32x4Instr* cast =
- new(Z) Float64x2ToFloat32x4Instr(
- new(Z) Value(call->ArgumentAt(1)), call->deopt_id());
- ReplaceCall(call, cast);
- return true;
- }
- return false;
-}
-
-
-bool JitOptimizer::TryInlineFloat64x2Constructor(
- StaticCallInstr* call,
- MethodRecognizer::Kind recognized_kind) {
- if (!ShouldInlineSimd()) {
- return false;
- }
- if (recognized_kind == MethodRecognizer::kFloat64x2Zero) {
- Float64x2ZeroInstr* zero = new(Z) Float64x2ZeroInstr();
- ReplaceCall(call, zero);
- return true;
- } else if (recognized_kind == MethodRecognizer::kFloat64x2Splat) {
- Float64x2SplatInstr* splat =
- new(Z) Float64x2SplatInstr(
- new(Z) Value(call->ArgumentAt(1)), call->deopt_id());
- ReplaceCall(call, splat);
- return true;
- } else if (recognized_kind == MethodRecognizer::kFloat64x2Constructor) {
- Float64x2ConstructorInstr* con =
- new(Z) Float64x2ConstructorInstr(
- new(Z) Value(call->ArgumentAt(1)),
- new(Z) Value(call->ArgumentAt(2)),
- call->deopt_id());
- ReplaceCall(call, con);
- return true;
- } else if (recognized_kind == MethodRecognizer::kFloat64x2FromFloat32x4) {
- Float32x4ToFloat64x2Instr* cast =
- new(Z) Float32x4ToFloat64x2Instr(
- new(Z) Value(call->ArgumentAt(1)), call->deopt_id());
- ReplaceCall(call, cast);
- return true;
- }
- return false;
-}
-
-
-bool JitOptimizer::TryInlineInt32x4Constructor(
- StaticCallInstr* call,
- MethodRecognizer::Kind recognized_kind) {
- if (!ShouldInlineSimd()) {
- return false;
- }
- if (recognized_kind == MethodRecognizer::kInt32x4BoolConstructor) {
- Int32x4BoolConstructorInstr* con =
- new(Z) Int32x4BoolConstructorInstr(
- new(Z) Value(call->ArgumentAt(1)),
- new(Z) Value(call->ArgumentAt(2)),
- new(Z) Value(call->ArgumentAt(3)),
- new(Z) Value(call->ArgumentAt(4)),
- call->deopt_id());
- ReplaceCall(call, con);
- return true;
- } else if (recognized_kind == MethodRecognizer::kInt32x4FromFloat32x4Bits) {
- Float32x4ToInt32x4Instr* cast =
- new(Z) Float32x4ToInt32x4Instr(
- new(Z) Value(call->ArgumentAt(1)), call->deopt_id());
- ReplaceCall(call, cast);
- return true;
- } else if (recognized_kind == MethodRecognizer::kInt32x4Constructor) {
- Int32x4ConstructorInstr* con =
- new(Z) Int32x4ConstructorInstr(
- new(Z) Value(call->ArgumentAt(1)),
- new(Z) Value(call->ArgumentAt(2)),
- new(Z) Value(call->ArgumentAt(3)),
- new(Z) Value(call->ArgumentAt(4)),
- call->deopt_id());
- ReplaceCall(call, con);
- return true;
- }
return false;
}
-bool JitOptimizer::TryInlineFloat32x4Method(
- InstanceCallInstr* call,
- MethodRecognizer::Kind recognized_kind) {
- if (!ShouldInlineSimd()) {
- return false;
- }
- ASSERT(call->HasICData());
- switch (recognized_kind) {
- case MethodRecognizer::kFloat32x4ShuffleX:
- case MethodRecognizer::kFloat32x4ShuffleY:
- case MethodRecognizer::kFloat32x4ShuffleZ:
- case MethodRecognizer::kFloat32x4ShuffleW:
- case MethodRecognizer::kFloat32x4GetSignMask:
- ASSERT(call->ic_data()->HasReceiverClassId(kFloat32x4Cid));
- ASSERT(call->ic_data()->HasOneTarget());
- return InlineFloat32x4Getter(call, recognized_kind);
-
- case MethodRecognizer::kFloat32x4Equal:
- case MethodRecognizer::kFloat32x4GreaterThan:
- case MethodRecognizer::kFloat32x4GreaterThanOrEqual:
- case MethodRecognizer::kFloat32x4LessThan:
- case MethodRecognizer::kFloat32x4LessThanOrEqual:
- case MethodRecognizer::kFloat32x4NotEqual: {
- Definition* left = call->ArgumentAt(0);
- Definition* right = call->ArgumentAt(1);
- Float32x4ComparisonInstr* cmp =
- new(Z) Float32x4ComparisonInstr(recognized_kind,
- new(Z) Value(left),
- new(Z) Value(right),
- call->deopt_id());
- ReplaceCall(call, cmp);
- return true;
- }
- case MethodRecognizer::kFloat32x4Min:
- case MethodRecognizer::kFloat32x4Max: {
- Definition* left = call->ArgumentAt(0);
- Definition* right = call->ArgumentAt(1);
- Float32x4MinMaxInstr* minmax =
- new(Z) Float32x4MinMaxInstr(
- recognized_kind,
- new(Z) Value(left),
- new(Z) Value(right),
- call->deopt_id());
- ReplaceCall(call, minmax);
- return true;
- }
- case MethodRecognizer::kFloat32x4Scale: {
- Definition* left = call->ArgumentAt(0);
- Definition* right = call->ArgumentAt(1);
- // Left and right values are swapped when handed to the instruction,
- // this is done so that the double value is loaded into the output
- // register and can be destroyed.
- Float32x4ScaleInstr* scale =
- new(Z) Float32x4ScaleInstr(recognized_kind,
- new(Z) Value(right),
- new(Z) Value(left),
- call->deopt_id());
- ReplaceCall(call, scale);
- return true;
- }
- case MethodRecognizer::kFloat32x4Sqrt:
- case MethodRecognizer::kFloat32x4ReciprocalSqrt:
- case MethodRecognizer::kFloat32x4Reciprocal: {
- Definition* left = call->ArgumentAt(0);
- Float32x4SqrtInstr* sqrt =
- new(Z) Float32x4SqrtInstr(recognized_kind,
- new(Z) Value(left),
- call->deopt_id());
- ReplaceCall(call, sqrt);
- return true;
- }
- case MethodRecognizer::kFloat32x4WithX:
- case MethodRecognizer::kFloat32x4WithY:
- case MethodRecognizer::kFloat32x4WithZ:
- case MethodRecognizer::kFloat32x4WithW: {
- Definition* left = call->ArgumentAt(0);
- Definition* right = call->ArgumentAt(1);
- Float32x4WithInstr* with = new(Z) Float32x4WithInstr(recognized_kind,
- new(Z) Value(left),
- new(Z) Value(right),
- call->deopt_id());
- ReplaceCall(call, with);
- return true;
- }
- case MethodRecognizer::kFloat32x4Absolute:
- case MethodRecognizer::kFloat32x4Negate: {
- Definition* left = call->ArgumentAt(0);
- Float32x4ZeroArgInstr* zeroArg =
- new(Z) Float32x4ZeroArgInstr(
- recognized_kind, new(Z) Value(left), call->deopt_id());
- ReplaceCall(call, zeroArg);
- return true;
- }
- case MethodRecognizer::kFloat32x4Clamp: {
- Definition* left = call->ArgumentAt(0);
- Definition* lower = call->ArgumentAt(1);
- Definition* upper = call->ArgumentAt(2);
- Float32x4ClampInstr* clamp = new(Z) Float32x4ClampInstr(
- new(Z) Value(left),
- new(Z) Value(lower),
- new(Z) Value(upper),
- call->deopt_id());
- ReplaceCall(call, clamp);
- return true;
- }
- case MethodRecognizer::kFloat32x4ShuffleMix:
- case MethodRecognizer::kFloat32x4Shuffle: {
- return InlineFloat32x4Getter(call, recognized_kind);
- }
- default:
- return false;
- }
-}
-
-
-bool JitOptimizer::TryInlineFloat64x2Method(
- InstanceCallInstr* call,
- MethodRecognizer::Kind recognized_kind) {
- if (!ShouldInlineSimd()) {
- return false;
- }
- ASSERT(call->HasICData());
- switch (recognized_kind) {
- case MethodRecognizer::kFloat64x2GetX:
- case MethodRecognizer::kFloat64x2GetY:
- ASSERT(call->ic_data()->HasReceiverClassId(kFloat64x2Cid));
- ASSERT(call->ic_data()->HasOneTarget());
- return InlineFloat64x2Getter(call, recognized_kind);
- case MethodRecognizer::kFloat64x2Negate:
- case MethodRecognizer::kFloat64x2Abs:
- case MethodRecognizer::kFloat64x2Sqrt:
- case MethodRecognizer::kFloat64x2GetSignMask: {
- Definition* left = call->ArgumentAt(0);
- Float64x2ZeroArgInstr* zeroArg =
- new(Z) Float64x2ZeroArgInstr(
- recognized_kind, new(Z) Value(left), call->deopt_id());
- ReplaceCall(call, zeroArg);
- return true;
- }
- case MethodRecognizer::kFloat64x2Scale:
- case MethodRecognizer::kFloat64x2WithX:
- case MethodRecognizer::kFloat64x2WithY:
- case MethodRecognizer::kFloat64x2Min:
- case MethodRecognizer::kFloat64x2Max: {
- Definition* left = call->ArgumentAt(0);
- Definition* right = call->ArgumentAt(1);
- Float64x2OneArgInstr* zeroArg =
- new(Z) Float64x2OneArgInstr(recognized_kind,
- new(Z) Value(left),
- new(Z) Value(right),
- call->deopt_id());
- ReplaceCall(call, zeroArg);
- return true;
- }
- default:
- return false;
- }
-}
-
-
-bool JitOptimizer::TryInlineInt32x4Method(
- InstanceCallInstr* call,
- MethodRecognizer::Kind recognized_kind) {
- if (!ShouldInlineSimd()) {
- return false;
- }
- ASSERT(call->HasICData());
- switch (recognized_kind) {
- case MethodRecognizer::kInt32x4ShuffleMix:
- case MethodRecognizer::kInt32x4Shuffle:
- case MethodRecognizer::kInt32x4GetFlagX:
- case MethodRecognizer::kInt32x4GetFlagY:
- case MethodRecognizer::kInt32x4GetFlagZ:
- case MethodRecognizer::kInt32x4GetFlagW:
- case MethodRecognizer::kInt32x4GetSignMask:
- ASSERT(call->ic_data()->HasReceiverClassId(kInt32x4Cid));
- ASSERT(call->ic_data()->HasOneTarget());
- return InlineInt32x4Getter(call, recognized_kind);
-
- case MethodRecognizer::kInt32x4Select: {
- Definition* mask = call->ArgumentAt(0);
- Definition* trueValue = call->ArgumentAt(1);
- Definition* falseValue = call->ArgumentAt(2);
- // Type check left.
- AddCheckClass(mask,
- ICData::ZoneHandle(
- Z, call->ic_data()->AsUnaryClassChecksForArgNr(0)),
- call->deopt_id(),
- call->env(),
- call);
- Int32x4SelectInstr* select = new(Z) Int32x4SelectInstr(
- new(Z) Value(mask),
- new(Z) Value(trueValue),
- new(Z) Value(falseValue),
- call->deopt_id());
- ReplaceCall(call, select);
- return true;
- }
- case MethodRecognizer::kInt32x4WithFlagX:
- case MethodRecognizer::kInt32x4WithFlagY:
- case MethodRecognizer::kInt32x4WithFlagZ:
- case MethodRecognizer::kInt32x4WithFlagW: {
- Definition* left = call->ArgumentAt(0);
- Definition* flag = call->ArgumentAt(1);
- // Type check left.
- AddCheckClass(left,
- ICData::ZoneHandle(
- Z, call->ic_data()->AsUnaryClassChecksForArgNr(0)),
- call->deopt_id(),
- call->env(),
- call);
- Int32x4SetFlagInstr* setFlag = new(Z) Int32x4SetFlagInstr(
- recognized_kind,
- new(Z) Value(left),
- new(Z) Value(flag),
- call->deopt_id());
- ReplaceCall(call, setFlag);
- return true;
- }
- default:
- return false;
- }
-}
-
-
// If type tests specified by 'ic_data' do not depend on type arguments,
// return mapping cid->result in 'results' (i : cid; i + 1: result).
// If all tests yield the same result, return it otherwise return Bool::null.
@@ -2637,17 +2138,14 @@ void JitOptimizer::VisitStaticCall(StaticCallInstr* call) {
case MethodRecognizer::kFloat32x4Splat:
case MethodRecognizer::kFloat32x4Constructor:
case MethodRecognizer::kFloat32x4FromFloat64x2:
- TryInlineFloat32x4Constructor(call, recognized_kind);
- break;
case MethodRecognizer::kFloat64x2Constructor:
case MethodRecognizer::kFloat64x2Zero:
case MethodRecognizer::kFloat64x2Splat:
case MethodRecognizer::kFloat64x2FromFloat32x4:
- TryInlineFloat64x2Constructor(call, recognized_kind);
- break;
case MethodRecognizer::kInt32x4BoolConstructor:
case MethodRecognizer::kInt32x4Constructor:
- TryInlineInt32x4Constructor(call, recognized_kind);
+ FlowGraphInliner::TryReplaceStaticCallWithInline(
+ flow_graph_, current_iterator(), call);
break;
case MethodRecognizer::kObjectConstructor: {
// Remove the original push arguments.
« runtime/vm/flow_graph_inliner.cc ('K') | « runtime/vm/jit_optimizer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698