| Index: runtime/vm/aot_optimizer.cc
|
| diff --git a/runtime/vm/aot_optimizer.cc b/runtime/vm/aot_optimizer.cc
|
| index 856766f1ac74f4b5aebe217b7c15b9290fb45df3..c938bc3799a82e1860e3385892e05e7e663c503f 100644
|
| --- a/runtime/vm/aot_optimizer.cc
|
| +++ b/runtime/vm/aot_optimizer.cc
|
| @@ -72,12 +72,10 @@ static void GetUniqueDynamicTarget(Isolate* isolate,
|
| }
|
|
|
|
|
| -AotOptimizer::AotOptimizer(Precompiler* precompiler,
|
| - FlowGraph* flow_graph,
|
| +AotOptimizer::AotOptimizer(FlowGraph* flow_graph,
|
| bool use_speculative_inlining,
|
| GrowableArray<intptr_t>* inlining_black_list)
|
| : FlowGraphVisitor(flow_graph->reverse_postorder()),
|
| - precompiler_(precompiler),
|
| flow_graph_(flow_graph),
|
| use_speculative_inlining_(use_speculative_inlining),
|
| inlining_black_list_(inlining_black_list),
|
| @@ -126,47 +124,6 @@ void AotOptimizer::PopulateWithICData() {
|
| }
|
|
|
|
|
| -bool AotOptimizer::RecognizeRuntimeTypeGetter(InstanceCallInstr* call) {
|
| - if ((precompiler_ == NULL) || !precompiler_->get_runtime_type_is_unique()) {
|
| - return false;
|
| - }
|
| -
|
| - if (call->function_name().raw() != Symbols::GetRuntimeType().raw()) {
|
| - return false;
|
| - }
|
| -
|
| - // There is only a single function Object.get:runtimeType that can be invoked
|
| - // by this call. Convert dynamic invocation to a static one.
|
| - const Class& cls = Class::Handle(Z, I->object_store()->object_class());
|
| - const Array& args_desc_array = Array::Handle(Z,
|
| - ArgumentsDescriptor::New(call->ArgumentCount(),
|
| - call->argument_names()));
|
| - ArgumentsDescriptor args_desc(args_desc_array);
|
| - const Function& function = Function::Handle(Z,
|
| - Resolver::ResolveDynamicForReceiverClass(
|
| - cls,
|
| - call->function_name(),
|
| - args_desc));
|
| - ASSERT(!function.IsNull());
|
| -
|
| - ZoneGrowableArray<PushArgumentInstr*>* args =
|
| - new (Z) ZoneGrowableArray<PushArgumentInstr*>(
|
| - call->ArgumentCount());
|
| - for (intptr_t i = 0; i < call->ArgumentCount(); i++) {
|
| - args->Add(call->PushArgumentAt(i));
|
| - }
|
| - StaticCallInstr* static_call = new (Z) StaticCallInstr(
|
| - call->token_pos(),
|
| - Function::ZoneHandle(Z, function.raw()),
|
| - call->argument_names(),
|
| - args,
|
| - call->deopt_id());
|
| - static_call->set_result_cid(kTypeCid);
|
| - call->ReplaceWith(static_call, current_iterator());
|
| - return true;
|
| -}
|
| -
|
| -
|
| // 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
|
| @@ -672,58 +629,6 @@ bool AotOptimizer::TryStringLengthOneEquality(InstanceCallInstr* call,
|
|
|
| static bool SmiFitsInDouble() { return kSmiBits < 53; }
|
|
|
| -
|
| -static bool IsGetRuntimeType(Definition* defn) {
|
| - StaticCallInstr* call = defn->AsStaticCall();
|
| - return (call != NULL) &&
|
| - (call->function().recognized_kind() ==
|
| - MethodRecognizer::kObjectRuntimeType);
|
| -}
|
| -
|
| -
|
| -// Recognize a.runtimeType == b.runtimeType and fold it into
|
| -// Object._haveSameRuntimeType(a, b).
|
| -// Note: this optimization is not speculative.
|
| -bool AotOptimizer::TryReplaceWithHaveSameRuntimeType(InstanceCallInstr* call) {
|
| - const ICData& ic_data = *call->ic_data();
|
| - ASSERT(ic_data.NumArgsTested() == 2);
|
| -
|
| - ASSERT(call->ArgumentCount() == 2);
|
| - Definition* left = call->ArgumentAt(0);
|
| - Definition* right = call->ArgumentAt(1);
|
| -
|
| - if (IsGetRuntimeType(left) && left->input_use_list()->IsSingleUse() &&
|
| - IsGetRuntimeType(right) && right->input_use_list()->IsSingleUse()) {
|
| - const Class& cls = Class::Handle(Z, I->object_store()->object_class());
|
| - const Function& have_same_runtime_type = Function::ZoneHandle(Z,
|
| - cls.LookupStaticFunctionAllowPrivate(Symbols::HaveSameRuntimeType()));
|
| - ASSERT(!have_same_runtime_type.IsNull());
|
| -
|
| - ZoneGrowableArray<PushArgumentInstr*>* args =
|
| - new (Z) ZoneGrowableArray<PushArgumentInstr*>(2);
|
| - PushArgumentInstr* arg = new (Z) PushArgumentInstr(
|
| - new (Z) Value(left->ArgumentAt(0)));
|
| - InsertBefore(call, arg, NULL, FlowGraph::kEffect);
|
| - args->Add(arg);
|
| - arg = new (Z) PushArgumentInstr(
|
| - new (Z) Value(right->ArgumentAt(0)));
|
| - InsertBefore(call, arg, NULL, FlowGraph::kEffect);
|
| - args->Add(arg);
|
| - StaticCallInstr* static_call = new (Z) StaticCallInstr(
|
| - call->token_pos(),
|
| - have_same_runtime_type,
|
| - Object::null_array(), // argument_names
|
| - args,
|
| - call->deopt_id());
|
| - static_call->set_result_cid(kBoolCid);
|
| - ReplaceCall(call, static_call);
|
| - return true;
|
| - }
|
| -
|
| - return false;
|
| -}
|
| -
|
| -
|
| bool AotOptimizer::TryReplaceWithEqualityOp(InstanceCallInstr* call,
|
| Token::Kind op_kind) {
|
| const ICData& ic_data = *call->ic_data();
|
| @@ -735,7 +640,11 @@ bool AotOptimizer::TryReplaceWithEqualityOp(InstanceCallInstr* call,
|
|
|
| intptr_t cid = kIllegalCid;
|
| if (HasOnlyTwoOf(ic_data, kOneByteStringCid)) {
|
| - return TryStringLengthOneEquality(call, op_kind);
|
| + if (TryStringLengthOneEquality(call, op_kind)) {
|
| + return true;
|
| + } else {
|
| + return false;
|
| + }
|
| } else if (HasOnlyTwoOf(ic_data, kSmiCid)) {
|
| InsertBefore(call,
|
| new(Z) CheckSmiInstr(new(Z) Value(left),
|
| @@ -801,8 +710,6 @@ bool AotOptimizer::TryReplaceWithEqualityOp(InstanceCallInstr* call,
|
| cid = kSmiCid;
|
| } else {
|
| // Shortcut for equality with null.
|
| - // TODO(vegorov): this optimization is not speculative and should
|
| - // be hoisted out of this function.
|
| ConstantInstr* right_const = right->AsConstant();
|
| ConstantInstr* left_const = left->AsConstant();
|
| if ((right_const != NULL && right_const->value().IsNull()) ||
|
| @@ -1850,14 +1757,6 @@ void AotOptimizer::VisitInstanceCall(InstanceCallInstr* instr) {
|
| return;
|
| }
|
|
|
| - if (RecognizeRuntimeTypeGetter(instr)) {
|
| - return;
|
| - }
|
| -
|
| - if ((op_kind == Token::kEQ) && TryReplaceWithHaveSameRuntimeType(instr)) {
|
| - return;
|
| - }
|
| -
|
| const ICData& unary_checks =
|
| ICData::ZoneHandle(Z, instr->ic_data()->AsUnaryClassChecks());
|
| if (IsAllowedForInlining(instr->deopt_id()) &&
|
|
|