Index: runtime/vm/jit_optimizer.cc |
diff --git a/runtime/vm/jit_optimizer.cc b/runtime/vm/jit_optimizer.cc |
index 41c3341e42295e174595e6835f5b78c7806d3a01..61df7ea64f5b381830aa9db3264411e16b8632b0 100644 |
--- a/runtime/vm/jit_optimizer.cc |
+++ b/runtime/vm/jit_optimizer.cc |
@@ -36,23 +36,19 @@ static bool ShouldInlineSimd() { |
return FlowGraphCompiler::SupportsUnboxedSimd128(); |
} |
- |
static bool CanUnboxDouble() { |
return FlowGraphCompiler::SupportsUnboxedDoubles(); |
} |
- |
static bool CanConvertUnboxedMintToDouble() { |
return FlowGraphCompiler::CanConvertUnboxedMintToDouble(); |
} |
- |
// Optimize instance calls using ICData. |
void JitOptimizer::ApplyICData() { |
VisitBlocks(); |
} |
- |
// Optimize instance calls using cid. This is called after optimizer |
// converted instance calls to instructions. Any remaining |
// instance calls are either megamorphic calls, cannot be optimized or |
@@ -83,13 +79,11 @@ void JitOptimizer::ApplyClassIds() { |
} |
} |
- |
// TODO(srdjan): Test/support other number types as well. |
static bool IsNumberCid(intptr_t cid) { |
return (cid == kSmiCid) || (cid == kDoubleCid); |
} |
- |
bool JitOptimizer::TryCreateICData(InstanceCallInstr* call) { |
ASSERT(call->HasICData()); |
if (call->ic_data()->NumberOfUsedChecks() > 0) { |
@@ -196,7 +190,6 @@ bool JitOptimizer::TryCreateICData(InstanceCallInstr* call) { |
return false; |
} |
- |
void JitOptimizer::SpecializePolymorphicInstanceCall( |
PolymorphicInstanceCallInstr* call) { |
if (!FLAG_polymorphic_with_deopt) { |
@@ -227,7 +220,6 @@ void JitOptimizer::SpecializePolymorphicInstanceCall( |
call->ReplaceWith(specialized, current_iterator()); |
} |
- |
static bool ClassIdIsOneOf(intptr_t class_id, |
const GrowableArray<intptr_t>& class_ids) { |
for (intptr_t i = 0; i < class_ids.length(); i++) { |
@@ -239,7 +231,6 @@ static bool ClassIdIsOneOf(intptr_t class_id, |
return false; |
} |
- |
// Returns true if ICData tests two arguments and all ICData cids are in the |
// required sets 'receiver_class_ids' or 'argument_class_ids', respectively. |
static bool ICDataHasOnlyReceiverArgumentClassIds( |
@@ -264,7 +255,6 @@ static bool ICDataHasOnlyReceiverArgumentClassIds( |
return true; |
} |
- |
static bool ICDataHasReceiverArgumentClassIds(const ICData& ic_data, |
intptr_t receiver_class_id, |
intptr_t argument_class_id) { |
@@ -286,13 +276,11 @@ static bool ICDataHasReceiverArgumentClassIds(const ICData& ic_data, |
return false; |
} |
- |
static bool HasOnlyOneSmi(const ICData& ic_data) { |
return (ic_data.NumberOfUsedChecks() == 1) && |
ic_data.HasReceiverClassId(kSmiCid); |
} |
- |
static bool HasOnlySmiOrMint(const ICData& ic_data) { |
if (ic_data.NumberOfUsedChecks() == 1) { |
return ic_data.HasReceiverClassId(kSmiCid) || |
@@ -303,7 +291,6 @@ static bool HasOnlySmiOrMint(const ICData& ic_data) { |
ic_data.HasReceiverClassId(kMintCid); |
} |
- |
static bool HasOnlyTwoOf(const ICData& ic_data, intptr_t cid) { |
if (ic_data.NumberOfUsedChecks() != 1) { |
return false; |
@@ -331,7 +318,6 @@ static bool HasTwoMintOrSmi(const ICData& ic_data) { |
return true; |
} |
- |
// Returns false if the ICData contains anything other than the 4 combinations |
// of Double and Smi for the receiver and argument classes. |
static bool HasTwoDoubleOrSmi(const ICData& ic_data) { |
@@ -341,13 +327,11 @@ static bool HasTwoDoubleOrSmi(const ICData& ic_data) { |
return ICDataHasOnlyReceiverArgumentClassIds(ic_data, class_ids, class_ids); |
} |
- |
static bool HasOnlyOneDouble(const ICData& ic_data) { |
return (ic_data.NumberOfUsedChecks() == 1) && |
ic_data.HasReceiverClassId(kDoubleCid); |
} |
- |
static bool ShouldSpecializeForDouble(const ICData& ic_data) { |
// Don't specialize for double if we can't unbox them. |
if (!CanUnboxDouble()) { |
@@ -363,7 +347,6 @@ static bool ShouldSpecializeForDouble(const ICData& ic_data) { |
return HasTwoDoubleOrSmi(ic_data); |
} |
- |
void JitOptimizer::ReplaceCall(Definition* call, Definition* replacement) { |
// Remove the original push arguments. |
for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { |
@@ -374,7 +357,6 @@ void JitOptimizer::ReplaceCall(Definition* call, Definition* replacement) { |
call->ReplaceWith(replacement, current_iterator()); |
} |
- |
void JitOptimizer::AddCheckSmi(Definition* to_check, |
intptr_t deopt_id, |
Environment* deopt_environment, |
@@ -387,7 +369,6 @@ void JitOptimizer::AddCheckSmi(Definition* to_check, |
} |
} |
- |
void JitOptimizer::AddCheckClass(Definition* to_check, |
const Cids& cids, |
intptr_t deopt_id, |
@@ -399,7 +380,6 @@ void JitOptimizer::AddCheckClass(Definition* to_check, |
InsertBefore(insert_before, check, deopt_environment, FlowGraph::kEffect); |
} |
- |
void JitOptimizer::AddChecksForArgNr(InstanceCallInstr* call, |
Definition* instr, |
int argument_number) { |
@@ -407,7 +387,6 @@ void JitOptimizer::AddChecksForArgNr(InstanceCallInstr* call, |
AddCheckClass(instr, *cids, call->deopt_id(), call->env(), call); |
} |
- |
static bool ArgIsAlways(intptr_t cid, |
const ICData& ic_data, |
intptr_t arg_number) { |
@@ -424,7 +403,6 @@ static bool ArgIsAlways(intptr_t cid, |
return true; |
} |
- |
bool JitOptimizer::TryReplaceWithIndexedOp(InstanceCallInstr* call) { |
// Check for monomorphic IC data. |
if (!call->HasICData()) return false; |
@@ -437,7 +415,6 @@ bool JitOptimizer::TryReplaceWithIndexedOp(InstanceCallInstr* call) { |
flow_graph_, current_iterator(), call); |
} |
- |
// Return true if d is a string of length one (a constant or result from |
// from string-from-char-code instruction. |
static bool IsLengthOneString(Definition* d) { |
@@ -453,7 +430,6 @@ static bool IsLengthOneString(Definition* d) { |
} |
} |
- |
// Returns true if the string comparison was converted into char-code |
// comparison. Conversion is only possible for strings of length one. |
// E.g., detect str[x] == "x"; and use an integer comparison of char-codes. |
@@ -534,7 +510,6 @@ bool JitOptimizer::TryStringLengthOneEquality(InstanceCallInstr* call, |
return false; |
} |
- |
static bool SmiFitsInDouble() { |
return kSmiBits < 53; |
} |
@@ -578,10 +553,11 @@ bool JitOptimizer::TryReplaceWithEqualityOp(InstanceCallInstr* call, |
// call. |
return false; |
} else { |
- InsertBefore(call, new (Z) CheckEitherNonSmiInstr(new (Z) Value(left), |
- new (Z) Value(right), |
- call->deopt_id()), |
- call->env(), FlowGraph::kEffect); |
+ InsertBefore( |
+ call, |
+ new (Z) CheckEitherNonSmiInstr( |
+ new (Z) Value(left), new (Z) Value(right), call->deopt_id()), |
+ call->env(), FlowGraph::kEffect); |
cid = kDoubleCid; |
} |
} |
@@ -621,7 +597,6 @@ bool JitOptimizer::TryReplaceWithEqualityOp(InstanceCallInstr* call, |
return true; |
} |
- |
bool JitOptimizer::TryReplaceWithRelationalOp(InstanceCallInstr* call, |
Token::Kind op_kind) { |
const ICData& ic_data = *call->ic_data(); |
@@ -655,10 +630,11 @@ bool JitOptimizer::TryReplaceWithRelationalOp(InstanceCallInstr* call, |
// call. |
return false; |
} else { |
- InsertBefore(call, new (Z) CheckEitherNonSmiInstr(new (Z) Value(left), |
- new (Z) Value(right), |
- call->deopt_id()), |
- call->env(), FlowGraph::kEffect); |
+ InsertBefore( |
+ call, |
+ new (Z) CheckEitherNonSmiInstr( |
+ new (Z) Value(left), new (Z) Value(right), call->deopt_id()), |
+ call->env(), FlowGraph::kEffect); |
cid = kDoubleCid; |
} |
} |
@@ -673,7 +649,6 @@ bool JitOptimizer::TryReplaceWithRelationalOp(InstanceCallInstr* call, |
return true; |
} |
- |
bool JitOptimizer::TryReplaceWithBinaryOp(InstanceCallInstr* call, |
Token::Kind op_kind) { |
intptr_t operands_type = kIllegalCid; |
@@ -787,10 +762,11 @@ bool JitOptimizer::TryReplaceWithBinaryOp(InstanceCallInstr* call, |
// binary operation with two smis is a smi not a double, except '/' which |
// returns a double for two smis. |
if (op_kind != Token::kDIV) { |
- InsertBefore(call, new (Z) CheckEitherNonSmiInstr(new (Z) Value(left), |
- new (Z) Value(right), |
- call->deopt_id()), |
- call->env(), FlowGraph::kEffect); |
+ InsertBefore( |
+ call, |
+ new (Z) CheckEitherNonSmiInstr( |
+ new (Z) Value(left), new (Z) Value(right), call->deopt_id()), |
+ call->env(), FlowGraph::kEffect); |
} |
BinaryDoubleOpInstr* double_bin_op = new (Z) |
@@ -861,7 +837,6 @@ bool JitOptimizer::TryReplaceWithBinaryOp(InstanceCallInstr* call, |
return true; |
} |
- |
bool JitOptimizer::TryReplaceWithUnaryOp(InstanceCallInstr* call, |
Token::Kind op_kind) { |
ASSERT(call->ArgumentCount() == 1); |
@@ -892,7 +867,6 @@ bool JitOptimizer::TryReplaceWithUnaryOp(InstanceCallInstr* call, |
return true; |
} |
- |
// Using field class. |
RawField* JitOptimizer::GetField(intptr_t class_id, const String& field_name) { |
Class& cls = Class::Handle(Z, isolate()->class_table()->At(class_id)); |
@@ -912,7 +886,6 @@ RawField* JitOptimizer::GetField(intptr_t class_id, const String& field_name) { |
return Field::null(); |
} |
- |
bool JitOptimizer::InlineImplicitInstanceGetter(InstanceCallInstr* call) { |
ASSERT(call->HasICData()); |
const ICData& ic_data = *call->ic_data(); |
@@ -950,7 +923,6 @@ bool JitOptimizer::InlineImplicitInstanceGetter(InstanceCallInstr* call) { |
return true; |
} |
- |
bool JitOptimizer::InlineFloat32x4BinaryOp(InstanceCallInstr* call, |
Token::Kind op_kind) { |
if (!ShouldInlineSimd()) { |
@@ -970,7 +942,6 @@ bool JitOptimizer::InlineFloat32x4BinaryOp(InstanceCallInstr* call, |
return true; |
} |
- |
bool JitOptimizer::InlineInt32x4BinaryOp(InstanceCallInstr* call, |
Token::Kind op_kind) { |
if (!ShouldInlineSimd()) { |
@@ -989,7 +960,6 @@ bool JitOptimizer::InlineInt32x4BinaryOp(InstanceCallInstr* call, |
return true; |
} |
- |
bool JitOptimizer::InlineFloat64x2BinaryOp(InstanceCallInstr* call, |
Token::Kind op_kind) { |
if (!ShouldInlineSimd()) { |
@@ -1008,7 +978,6 @@ bool JitOptimizer::InlineFloat64x2BinaryOp(InstanceCallInstr* call, |
return true; |
} |
- |
// Only unique implicit instance getters can be currently handled. |
bool JitOptimizer::TryInlineInstanceGetter(InstanceCallInstr* call) { |
ASSERT(call->HasICData()); |
@@ -1033,7 +1002,6 @@ bool JitOptimizer::TryInlineInstanceGetter(InstanceCallInstr* call) { |
return InlineImplicitInstanceGetter(call); |
} |
- |
void JitOptimizer::ReplaceWithMathCFunction( |
InstanceCallInstr* call, |
MethodRecognizer::Kind recognized_kind) { |
@@ -1048,7 +1016,6 @@ void JitOptimizer::ReplaceWithMathCFunction( |
ReplaceCall(call, invoke); |
} |
- |
// Inline only simple, frequently called core library methods. |
bool JitOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { |
ASSERT(call->HasICData()); |
@@ -1129,7 +1096,6 @@ bool JitOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { |
flow_graph_, current_iterator(), call); |
} |
- |
// 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. |
@@ -1197,7 +1163,6 @@ RawBool* JitOptimizer::InstanceOfAsBool( |
return results_differ ? Bool::null() : prev.raw(); |
} |
- |
// Returns true if checking against this type is a direct class id comparison. |
bool JitOptimizer::TypeCheckAsClassEquality(const AbstractType& type) { |
ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded()); |
@@ -1244,7 +1209,6 @@ bool JitOptimizer::TypeCheckAsClassEquality(const AbstractType& type) { |
return true; |
} |
- |
// TODO(srdjan): Use ICData to check if always true or false. |
void JitOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) { |
ASSERT(Token::IsTypeTestOperator(call->token_kind())); |
@@ -1321,7 +1285,6 @@ void JitOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) { |
ReplaceCall(call, instance_of); |
} |
- |
// TODO(srdjan): Apply optimizations as in ReplaceWithInstanceOf (TestCids). |
void JitOptimizer::ReplaceWithTypeCast(InstanceCallInstr* call) { |
ASSERT(Token::IsTypeCastOperator(call->token_kind())); |
@@ -1362,7 +1325,6 @@ void JitOptimizer::ReplaceWithTypeCast(InstanceCallInstr* call) { |
ReplaceCall(call, assert_as); |
} |
- |
// Tries to optimize instance call by replacing it with a faster instruction |
// (e.g, binary op, field load, ..). |
void JitOptimizer::VisitInstanceCall(InstanceCallInstr* instr) { |
@@ -1479,7 +1441,6 @@ void JitOptimizer::VisitInstanceCall(InstanceCallInstr* instr) { |
} |
} |
- |
void JitOptimizer::VisitStaticCall(StaticCallInstr* call) { |
MethodRecognizer::Kind recognized_kind = |
MethodRecognizer::RecognizeKind(call->function()); |
@@ -1562,7 +1523,6 @@ void JitOptimizer::VisitStaticCall(StaticCallInstr* call) { |
} |
} |
- |
void JitOptimizer::VisitStoreInstanceField(StoreInstanceFieldInstr* instr) { |
if (instr->IsUnboxedStore()) { |
// Determine if this field should be unboxed based on the usage of getter |
@@ -1616,7 +1576,6 @@ void JitOptimizer::VisitStoreInstanceField(StoreInstanceFieldInstr* instr) { |
} |
} |
- |
void JitOptimizer::VisitAllocateContext(AllocateContextInstr* instr) { |
// Replace generic allocation with a sequence of inlined allocation and |
// explicit initializing stores. |
@@ -1647,7 +1606,6 @@ void JitOptimizer::VisitAllocateContext(AllocateContextInstr* instr) { |
} |
} |
- |
void JitOptimizer::VisitLoadCodeUnits(LoadCodeUnitsInstr* instr) { |
// TODO(zerny): Use kUnboxedUint32 once it is fully supported/optimized. |
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM) |
@@ -1655,7 +1613,6 @@ void JitOptimizer::VisitLoadCodeUnits(LoadCodeUnitsInstr* instr) { |
#endif |
} |
- |
bool JitOptimizer::TryInlineInstanceSetter(InstanceCallInstr* instr, |
const ICData& unary_ic_data) { |
ASSERT(!unary_ic_data.NumberOfChecksIs(0) && |
@@ -1695,17 +1652,19 @@ bool JitOptimizer::TryInlineInstanceSetter(InstanceCallInstr* instr, |
} |
if (field.guarded_cid() != kDynamicCid) { |
ASSERT(I->use_field_guards()); |
- InsertBefore( |
- instr, new (Z) GuardFieldClassInstr(new (Z) Value(instr->ArgumentAt(1)), |
- field, instr->deopt_id()), |
- instr->env(), FlowGraph::kEffect); |
+ InsertBefore(instr, |
+ new (Z) |
+ GuardFieldClassInstr(new (Z) Value(instr->ArgumentAt(1)), |
+ field, instr->deopt_id()), |
+ instr->env(), FlowGraph::kEffect); |
} |
if (field.needs_length_check()) { |
ASSERT(I->use_field_guards()); |
- InsertBefore(instr, new (Z) GuardFieldLengthInstr( |
- new (Z) Value(instr->ArgumentAt(1)), field, |
- instr->deopt_id()), |
+ InsertBefore(instr, |
+ new (Z) |
+ GuardFieldLengthInstr(new (Z) Value(instr->ArgumentAt(1)), |
+ field, instr->deopt_id()), |
instr->env(), FlowGraph::kEffect); |
} |
@@ -1726,6 +1685,5 @@ bool JitOptimizer::TryInlineInstanceSetter(InstanceCallInstr* instr, |
return true; |
} |
- |
} // namespace dart |
#endif // DART_PRECOMPILED_RUNTIME |