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

Side by Side Diff: runtime/vm/flow_graph_optimizer.cc

Issue 1149713002: With --noopt run unoptimized code through optimizer, more optimizations can be done later. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: m Created 5 years, 6 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 unified diff | Download patch
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/flow_graph_optimizer.h" 5 #include "vm/flow_graph_optimizer.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/cha.h" 8 #include "vm/cha.h"
9 #include "vm/compiler.h"
9 #include "vm/cpu.h" 10 #include "vm/cpu.h"
10 #include "vm/dart_entry.h" 11 #include "vm/dart_entry.h"
11 #include "vm/exceptions.h" 12 #include "vm/exceptions.h"
12 #include "vm/flow_graph_builder.h" 13 #include "vm/flow_graph_builder.h"
13 #include "vm/flow_graph_compiler.h" 14 #include "vm/flow_graph_compiler.h"
14 #include "vm/flow_graph_range_analysis.h" 15 #include "vm/flow_graph_range_analysis.h"
15 #include "vm/hash_map.h" 16 #include "vm/hash_map.h"
16 #include "vm/il_printer.h" 17 #include "vm/il_printer.h"
17 #include "vm/intermediate_language.h" 18 #include "vm/intermediate_language.h"
18 #include "vm/object_store.h" 19 #include "vm/object_store.h"
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 #endif 81 #endif
81 } 82 }
82 83
83 84
84 // Optimize instance calls using ICData. 85 // Optimize instance calls using ICData.
85 void FlowGraphOptimizer::ApplyICData() { 86 void FlowGraphOptimizer::ApplyICData() {
86 VisitBlocks(); 87 VisitBlocks();
87 } 88 }
88 89
89 90
91 void FlowGraphOptimizer::PopulateWithICData() {
92 ASSERT(current_iterator_ == NULL);
93 for (intptr_t i = 0; i < block_order_.length(); ++i) {
94 BlockEntryInstr* entry = block_order_[i];
95 ForwardInstructionIterator it(entry);
96 for (; !it.Done(); it.Advance()) {
97 Instruction* instr = it.Current();
98 if (instr->IsInstanceCall()) {
99 InstanceCallInstr* call = instr->AsInstanceCall();
100 if (!call->HasICData()) {
101 const Array& arguments_descriptor =
102 Array::Handle(zone(),
103 ArgumentsDescriptor::New(call->ArgumentCount(),
104 call->argument_names()));
105 const ICData& ic_data = ICData::ZoneHandle(zone(), ICData::New(
106 function(), call->function_name(),
107 arguments_descriptor, call->deopt_id(),
108 call->checked_argument_count()));
109 call->set_ic_data(&ic_data);
110 }
111 }
112 }
113 current_iterator_ = NULL;
114 }
115 }
116
117
90 // Optimize instance calls using cid. This is called after optimizer 118 // Optimize instance calls using cid. This is called after optimizer
91 // converted instance calls to instructions. Any remaining 119 // converted instance calls to instructions. Any remaining
92 // instance calls are either megamorphic calls, cannot be optimized or 120 // instance calls are either megamorphic calls, cannot be optimized or
93 // have no runtime type feedback collected. 121 // have no runtime type feedback collected.
94 // Attempts to convert an instance call (IC call) using propagated class-ids, 122 // Attempts to convert an instance call (IC call) using propagated class-ids,
95 // e.g., receiver class id, guarded-cid, or by guessing cid-s. 123 // e.g., receiver class id, guarded-cid, or by guessing cid-s.
96 void FlowGraphOptimizer::ApplyClassIds() { 124 void FlowGraphOptimizer::ApplyClassIds() {
97 ASSERT(current_iterator_ == NULL); 125 ASSERT(current_iterator_ == NULL);
98 for (intptr_t i = 0; i < block_order_.length(); ++i) { 126 for (intptr_t i = 0; i < block_order_.length(); ++i) {
99 BlockEntryInstr* entry = block_order_[i]; 127 BlockEntryInstr* entry = block_order_[i];
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 const intptr_t cid = call->PushArgumentAt(i)->value()->Type()->ToCid(); 183 const intptr_t cid = call->PushArgumentAt(i)->value()->Type()->ToCid();
156 class_ids.Add(cid); 184 class_ids.Add(cid);
157 } 185 }
158 186
159 const Token::Kind op_kind = call->token_kind(); 187 const Token::Kind op_kind = call->token_kind();
160 if (Token::IsRelationalOperator(op_kind) || 188 if (Token::IsRelationalOperator(op_kind) ||
161 Token::IsEqualityOperator(op_kind) || 189 Token::IsEqualityOperator(op_kind) ||
162 Token::IsBinaryOperator(op_kind)) { 190 Token::IsBinaryOperator(op_kind)) {
163 // Guess cid: if one of the inputs is a number assume that the other 191 // Guess cid: if one of the inputs is a number assume that the other
164 // is a number of same type. 192 // is a number of same type.
165 const intptr_t cid_0 = class_ids[0]; 193 if (Compiler::guess_other_cid()) {
166 const intptr_t cid_1 = class_ids[1]; 194 const intptr_t cid_0 = class_ids[0];
167 if ((cid_0 == kDynamicCid) && (IsNumberCid(cid_1))) { 195 const intptr_t cid_1 = class_ids[1];
168 class_ids[0] = cid_1; 196 if ((cid_0 == kDynamicCid) && (IsNumberCid(cid_1))) {
169 } else if (IsNumberCid(cid_0) && (cid_1 == kDynamicCid)) { 197 class_ids[0] = cid_1;
170 class_ids[1] = cid_0; 198 } else if (IsNumberCid(cid_0) && (cid_1 == kDynamicCid)) {
199 class_ids[1] = cid_0;
200 }
171 } 201 }
172 } 202 }
173 203
174 for (intptr_t i = 0; i < class_ids.length(); i++) { 204 for (intptr_t i = 0; i < class_ids.length(); i++) {
175 if (class_ids[i] == kDynamicCid) { 205 if (class_ids[i] == kDynamicCid) {
176 // Not all cid-s known. 206 // Not all cid-s known.
177 return false; 207 return false;
178 } 208 }
179 } 209 }
180 210
(...skipping 2075 matching lines...) Expand 10 before | Expand all | Expand 10 after
2256 const String& name = (kind == RawFunction::kMethodExtractor) 2286 const String& name = (kind == RawFunction::kMethodExtractor)
2257 ? String::Handle(Z, Field::NameFromGetter(call->function_name())) 2287 ? String::Handle(Z, Field::NameFromGetter(call->function_name()))
2258 : call->function_name(); 2288 : call->function_name();
2259 return thread()->cha()->HasOverride(Class::Handle(Z, function.Owner()), 2289 return thread()->cha()->HasOverride(Class::Handle(Z, function.Owner()),
2260 name); 2290 name);
2261 } 2291 }
2262 return true; 2292 return true;
2263 } 2293 }
2264 2294
2265 2295
2266 void FlowGraphOptimizer::InlineImplicitInstanceGetter(InstanceCallInstr* call) { 2296 bool FlowGraphOptimizer::InlineImplicitInstanceGetter(InstanceCallInstr* call,
2297 bool allow_check) {
2267 ASSERT(call->HasICData()); 2298 ASSERT(call->HasICData());
2268 const ICData& ic_data = *call->ic_data(); 2299 const ICData& ic_data = *call->ic_data();
2269 ASSERT(ic_data.HasOneTarget()); 2300 ASSERT(ic_data.HasOneTarget());
2270 Function& target = Function::Handle(Z); 2301 Function& target = Function::Handle(Z);
2271 GrowableArray<intptr_t> class_ids; 2302 GrowableArray<intptr_t> class_ids;
2272 ic_data.GetCheckAt(0, &class_ids, &target); 2303 ic_data.GetCheckAt(0, &class_ids, &target);
2273 ASSERT(class_ids.length() == 1); 2304 ASSERT(class_ids.length() == 1);
2274 // Inline implicit instance getter. 2305 // Inline implicit instance getter.
2275 const String& field_name = 2306 const String& field_name =
2276 String::Handle(Z, Field::NameFromGetter(call->function_name())); 2307 String::Handle(Z, Field::NameFromGetter(call->function_name()));
2277 const Field& field = 2308 const Field& field =
2278 Field::ZoneHandle(Z, GetField(class_ids[0], field_name)); 2309 Field::ZoneHandle(Z, GetField(class_ids[0], field_name));
2279 ASSERT(!field.IsNull()); 2310 ASSERT(!field.IsNull());
2280 2311
2281 if (InstanceCallNeedsClassCheck(call, RawFunction::kImplicitGetter)) { 2312 if (InstanceCallNeedsClassCheck(call, RawFunction::kImplicitGetter)) {
2313 if (!allow_check) {
2314 return false;
2315 }
2282 AddReceiverCheck(call); 2316 AddReceiverCheck(call);
2283 } 2317 }
2284 LoadFieldInstr* load = new(Z) LoadFieldInstr( 2318 LoadFieldInstr* load = new(Z) LoadFieldInstr(
2285 new(Z) Value(call->ArgumentAt(0)), 2319 new(Z) Value(call->ArgumentAt(0)),
2286 &field, 2320 &field,
2287 AbstractType::ZoneHandle(Z, field.type()), 2321 AbstractType::ZoneHandle(Z, field.type()),
2288 call->token_pos()); 2322 call->token_pos());
2289 load->set_is_immutable(field.is_final()); 2323 load->set_is_immutable(field.is_final());
2290 if (field.guarded_cid() != kIllegalCid) { 2324 if (field.guarded_cid() != kIllegalCid) {
2291 if (!field.is_nullable() || (field.guarded_cid() == kNullCid)) { 2325 if (!field.is_nullable() || (field.guarded_cid() == kNullCid)) {
2292 load->set_result_cid(field.guarded_cid()); 2326 load->set_result_cid(field.guarded_cid());
2293 } 2327 }
2294 FlowGraph::AddToGuardedFields(flow_graph_->guarded_fields(), &field); 2328 FlowGraph::AddToGuardedFields(flow_graph_->guarded_fields(), &field);
2295 } 2329 }
2296 2330
2297 // Discard the environment from the original instruction because the load 2331 // Discard the environment from the original instruction because the load
2298 // can't deoptimize. 2332 // can't deoptimize.
2299 call->RemoveEnvironment(); 2333 call->RemoveEnvironment();
2300 ReplaceCall(call, load); 2334 ReplaceCall(call, load);
2301 2335
2302 if (load->result_cid() != kDynamicCid) { 2336 if (load->result_cid() != kDynamicCid) {
2303 // Reset value types if guarded_cid was used. 2337 // Reset value types if guarded_cid was used.
2304 for (Value::Iterator it(load->input_use_list()); 2338 for (Value::Iterator it(load->input_use_list());
2305 !it.Done(); 2339 !it.Done();
2306 it.Advance()) { 2340 it.Advance()) {
2307 it.Current()->SetReachingType(NULL); 2341 it.Current()->SetReachingType(NULL);
2308 } 2342 }
2309 } 2343 }
2344 return true;
2310 } 2345 }
2311 2346
2312 2347
2313 bool FlowGraphOptimizer::InlineFloat32x4Getter(InstanceCallInstr* call, 2348 bool FlowGraphOptimizer::InlineFloat32x4Getter(InstanceCallInstr* call,
2314 MethodRecognizer::Kind getter) { 2349 MethodRecognizer::Kind getter) {
2315 if (!ShouldInlineSimd()) { 2350 if (!ShouldInlineSimd()) {
2316 return false; 2351 return false;
2317 } 2352 }
2318 AddCheckClass(call->ArgumentAt(0), 2353 AddCheckClass(call->ArgumentAt(0),
2319 ICData::ZoneHandle( 2354 ICData::ZoneHandle(
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
2577 BinaryFloat64x2OpInstr* float64x2_bin_op = 2612 BinaryFloat64x2OpInstr* float64x2_bin_op =
2578 new(Z) BinaryFloat64x2OpInstr( 2613 new(Z) BinaryFloat64x2OpInstr(
2579 op_kind, new(Z) Value(left), new(Z) Value(right), 2614 op_kind, new(Z) Value(left), new(Z) Value(right),
2580 call->deopt_id()); 2615 call->deopt_id());
2581 ReplaceCall(call, float64x2_bin_op); 2616 ReplaceCall(call, float64x2_bin_op);
2582 return true; 2617 return true;
2583 } 2618 }
2584 2619
2585 2620
2586 // Only unique implicit instance getters can be currently handled. 2621 // Only unique implicit instance getters can be currently handled.
2587 bool FlowGraphOptimizer::TryInlineInstanceGetter(InstanceCallInstr* call) { 2622 // Returns false if 'allow_check' is false and a check is needed.
2623 bool FlowGraphOptimizer::TryInlineInstanceGetter(InstanceCallInstr* call,
2624 bool allow_check) {
2588 ASSERT(call->HasICData()); 2625 ASSERT(call->HasICData());
2589 const ICData& ic_data = *call->ic_data(); 2626 const ICData& ic_data = *call->ic_data();
2590 if (ic_data.NumberOfUsedChecks() == 0) { 2627 if (ic_data.NumberOfUsedChecks() == 0) {
2591 // No type feedback collected. 2628 // No type feedback collected.
2592 return false; 2629 return false;
2593 } 2630 }
2594 2631
2595 if (!ic_data.HasOneTarget()) { 2632 if (!ic_data.HasOneTarget()) {
2596 // Polymorphic sites are inlined like normal methods by conventional 2633 // Polymorphic sites are inlined like normal methods by conventional
2597 // inlining in FlowGraphInliner. 2634 // inlining in FlowGraphInliner.
2598 return false; 2635 return false;
2599 } 2636 }
2600 2637
2601 const Function& target = Function::Handle(Z, ic_data.GetTargetAt(0)); 2638 const Function& target = Function::Handle(Z, ic_data.GetTargetAt(0));
2602 if (target.kind() != RawFunction::kImplicitGetter) { 2639 if (target.kind() != RawFunction::kImplicitGetter) {
2603 // Non-implicit getters are inlined like normal methods by conventional 2640 // Non-implicit getters are inlined like normal methods by conventional
2604 // inlining in FlowGraphInliner. 2641 // inlining in FlowGraphInliner.
2605 return false; 2642 return false;
2606 } 2643 }
2607 InlineImplicitInstanceGetter(call); 2644 return InlineImplicitInstanceGetter(call, allow_check);
2608 return true;
2609 } 2645 }
2610 2646
2611 2647
2612 bool FlowGraphOptimizer::TryReplaceInstanceCallWithInline( 2648 bool FlowGraphOptimizer::TryReplaceInstanceCallWithInline(
2613 InstanceCallInstr* call) { 2649 InstanceCallInstr* call) {
2614 Function& target = Function::Handle(Z); 2650 Function& target = Function::Handle(Z);
2615 GrowableArray<intptr_t> class_ids; 2651 GrowableArray<intptr_t> class_ids;
2616 call->ic_data()->GetCheckAt(0, &class_ids, &target); 2652 call->ic_data()->GetCheckAt(0, &class_ids, &target);
2617 const intptr_t receiver_cid = class_ids[0]; 2653 const intptr_t receiver_cid = class_ids[0];
2618 2654
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after
3119 return true; 3155 return true;
3120 } 3156 }
3121 } 3157 }
3122 return false; 3158 return false;
3123 } 3159 }
3124 3160
3125 3161
3126 bool FlowGraphOptimizer::TryInlineFloat32x4Constructor( 3162 bool FlowGraphOptimizer::TryInlineFloat32x4Constructor(
3127 StaticCallInstr* call, 3163 StaticCallInstr* call,
3128 MethodRecognizer::Kind recognized_kind) { 3164 MethodRecognizer::Kind recognized_kind) {
3165 if (Compiler::always_optimize()) {
3166 // Cannot handle unboxed instructions.
3167 return false;
3168 }
3129 if (!ShouldInlineSimd()) { 3169 if (!ShouldInlineSimd()) {
3130 return false; 3170 return false;
3131 } 3171 }
3132 if (recognized_kind == MethodRecognizer::kFloat32x4Zero) { 3172 if (recognized_kind == MethodRecognizer::kFloat32x4Zero) {
3133 Float32x4ZeroInstr* zero = new(Z) Float32x4ZeroInstr(); 3173 Float32x4ZeroInstr* zero = new(Z) Float32x4ZeroInstr();
3134 ReplaceCall(call, zero); 3174 ReplaceCall(call, zero);
3135 return true; 3175 return true;
3136 } else if (recognized_kind == MethodRecognizer::kFloat32x4Splat) { 3176 } else if (recognized_kind == MethodRecognizer::kFloat32x4Splat) {
3137 Float32x4SplatInstr* splat = 3177 Float32x4SplatInstr* splat =
3138 new(Z) Float32x4SplatInstr( 3178 new(Z) Float32x4SplatInstr(
(...skipping 23 matching lines...) Expand all
3162 ReplaceCall(call, cast); 3202 ReplaceCall(call, cast);
3163 return true; 3203 return true;
3164 } 3204 }
3165 return false; 3205 return false;
3166 } 3206 }
3167 3207
3168 3208
3169 bool FlowGraphOptimizer::TryInlineFloat64x2Constructor( 3209 bool FlowGraphOptimizer::TryInlineFloat64x2Constructor(
3170 StaticCallInstr* call, 3210 StaticCallInstr* call,
3171 MethodRecognizer::Kind recognized_kind) { 3211 MethodRecognizer::Kind recognized_kind) {
3212 if (Compiler::always_optimize()) {
3213 // Cannot handle unboxed instructions.
3214 return false;
3215 }
3172 if (!ShouldInlineSimd()) { 3216 if (!ShouldInlineSimd()) {
3173 return false; 3217 return false;
3174 } 3218 }
3175 if (recognized_kind == MethodRecognizer::kFloat64x2Zero) { 3219 if (recognized_kind == MethodRecognizer::kFloat64x2Zero) {
3176 Float64x2ZeroInstr* zero = new(Z) Float64x2ZeroInstr(); 3220 Float64x2ZeroInstr* zero = new(Z) Float64x2ZeroInstr();
3177 ReplaceCall(call, zero); 3221 ReplaceCall(call, zero);
3178 return true; 3222 return true;
3179 } else if (recognized_kind == MethodRecognizer::kFloat64x2Splat) { 3223 } else if (recognized_kind == MethodRecognizer::kFloat64x2Splat) {
3180 Float64x2SplatInstr* splat = 3224 Float64x2SplatInstr* splat =
3181 new(Z) Float64x2SplatInstr( 3225 new(Z) Float64x2SplatInstr(
(...skipping 15 matching lines...) Expand all
3197 ReplaceCall(call, cast); 3241 ReplaceCall(call, cast);
3198 return true; 3242 return true;
3199 } 3243 }
3200 return false; 3244 return false;
3201 } 3245 }
3202 3246
3203 3247
3204 bool FlowGraphOptimizer::TryInlineInt32x4Constructor( 3248 bool FlowGraphOptimizer::TryInlineInt32x4Constructor(
3205 StaticCallInstr* call, 3249 StaticCallInstr* call,
3206 MethodRecognizer::Kind recognized_kind) { 3250 MethodRecognizer::Kind recognized_kind) {
3251 if (Compiler::always_optimize()) {
3252 // Cannot handle unboxed instructions.
3253 return false;
3254 }
3207 if (!ShouldInlineSimd()) { 3255 if (!ShouldInlineSimd()) {
3208 return false; 3256 return false;
3209 } 3257 }
3210 if (recognized_kind == MethodRecognizer::kInt32x4BoolConstructor) { 3258 if (recognized_kind == MethodRecognizer::kInt32x4BoolConstructor) {
3211 Int32x4BoolConstructorInstr* con = 3259 Int32x4BoolConstructorInstr* con =
3212 new(Z) Int32x4BoolConstructorInstr( 3260 new(Z) Int32x4BoolConstructorInstr(
3213 new(Z) Value(call->ArgumentAt(1)), 3261 new(Z) Value(call->ArgumentAt(1)),
3214 new(Z) Value(call->ArgumentAt(2)), 3262 new(Z) Value(call->ArgumentAt(2)),
3215 new(Z) Value(call->ArgumentAt(3)), 3263 new(Z) Value(call->ArgumentAt(3)),
3216 new(Z) Value(call->ArgumentAt(4)), 3264 new(Z) Value(call->ArgumentAt(4)),
(...skipping 928 matching lines...) Expand 10 before | Expand all | Expand 10 after
4145 4193
4146 4194
4147 // Tries to optimize instance call by replacing it with a faster instruction 4195 // Tries to optimize instance call by replacing it with a faster instruction
4148 // (e.g, binary op, field load, ..). 4196 // (e.g, binary op, field load, ..).
4149 void FlowGraphOptimizer::VisitInstanceCall(InstanceCallInstr* instr) { 4197 void FlowGraphOptimizer::VisitInstanceCall(InstanceCallInstr* instr) {
4150 if (!instr->HasICData() || (instr->ic_data()->NumberOfUsedChecks() == 0)) { 4198 if (!instr->HasICData() || (instr->ic_data()->NumberOfUsedChecks() == 0)) {
4151 return; 4199 return;
4152 } 4200 }
4153 4201
4154 const Token::Kind op_kind = instr->token_kind(); 4202 const Token::Kind op_kind = instr->token_kind();
4203 if (Compiler::always_optimize()) {
4204 // TODO(srdjan): Investigate other attempts, as they are not allowed to
4205 // deoptimize.
4206 if ((op_kind == Token::kGET) && TryInlineInstanceGetter(instr, false)) {
4207 return;
4208 }
4209 return;
4210 }
4211
4155 // Type test is special as it always gets converted into inlined code. 4212 // Type test is special as it always gets converted into inlined code.
4156 if (Token::IsTypeTestOperator(op_kind)) { 4213 if (Token::IsTypeTestOperator(op_kind)) {
4157 ReplaceWithInstanceOf(instr); 4214 ReplaceWithInstanceOf(instr);
4158 return; 4215 return;
4159 } 4216 }
4160 4217
4161 if (Token::IsTypeCastOperator(op_kind)) { 4218 if (Token::IsTypeCastOperator(op_kind)) {
4162 ReplaceWithTypeCast(instr); 4219 ReplaceWithTypeCast(instr);
4163 return; 4220 return;
4164 } 4221 }
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
4268 unary_kind = MathUnaryInstr::kSin; 4325 unary_kind = MathUnaryInstr::kSin;
4269 break; 4326 break;
4270 case MethodRecognizer::kMathCos: 4327 case MethodRecognizer::kMathCos:
4271 unary_kind = MathUnaryInstr::kCos; 4328 unary_kind = MathUnaryInstr::kCos;
4272 break; 4329 break;
4273 default: 4330 default:
4274 unary_kind = MathUnaryInstr::kIllegal; 4331 unary_kind = MathUnaryInstr::kIllegal;
4275 break; 4332 break;
4276 } 4333 }
4277 if (unary_kind != MathUnaryInstr::kIllegal) { 4334 if (unary_kind != MathUnaryInstr::kIllegal) {
4278 MathUnaryInstr* math_unary = 4335 if (Compiler::always_optimize()) {
4279 new(Z) MathUnaryInstr(unary_kind, 4336 // TODO(srdjan): Adapt MathUnaryInstr to allow tagged inputs as well.
4280 new(Z) Value(call->ArgumentAt(0)), 4337 } else {
4281 call->deopt_id()); 4338 MathUnaryInstr* math_unary =
4282 ReplaceCall(call, math_unary); 4339 new(Z) MathUnaryInstr(unary_kind,
4340 new(Z) Value(call->ArgumentAt(0)),
4341 call->deopt_id());
4342 ReplaceCall(call, math_unary);
4343 }
4283 } else if ((recognized_kind == MethodRecognizer::kFloat32x4Zero) || 4344 } else if ((recognized_kind == MethodRecognizer::kFloat32x4Zero) ||
4284 (recognized_kind == MethodRecognizer::kFloat32x4Splat) || 4345 (recognized_kind == MethodRecognizer::kFloat32x4Splat) ||
4285 (recognized_kind == MethodRecognizer::kFloat32x4Constructor) || 4346 (recognized_kind == MethodRecognizer::kFloat32x4Constructor) ||
4286 (recognized_kind == MethodRecognizer::kFloat32x4FromFloat64x2)) { 4347 (recognized_kind == MethodRecognizer::kFloat32x4FromFloat64x2)) {
4287 TryInlineFloat32x4Constructor(call, recognized_kind); 4348 TryInlineFloat32x4Constructor(call, recognized_kind);
4288 } else if ((recognized_kind == MethodRecognizer::kFloat64x2Constructor) || 4349 } else if ((recognized_kind == MethodRecognizer::kFloat64x2Constructor) ||
4289 (recognized_kind == MethodRecognizer::kFloat64x2Zero) || 4350 (recognized_kind == MethodRecognizer::kFloat64x2Zero) ||
4290 (recognized_kind == MethodRecognizer::kFloat64x2Splat) || 4351 (recognized_kind == MethodRecognizer::kFloat64x2Splat) ||
4291 (recognized_kind == MethodRecognizer::kFloat64x2FromFloat32x4)) { 4352 (recognized_kind == MethodRecognizer::kFloat64x2FromFloat32x4)) {
4292 TryInlineFloat64x2Constructor(call, recognized_kind); 4353 TryInlineFloat64x2Constructor(call, recognized_kind);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
4333 call); 4394 call);
4334 AddCheckClass(min_max->right()->definition(), 4395 AddCheckClass(min_max->right()->definition(),
4335 unary_checks, 4396 unary_checks,
4336 call->deopt_id(), 4397 call->deopt_id(),
4337 call->env(), 4398 call->env(),
4338 call); 4399 call);
4339 ReplaceCall(call, min_max); 4400 ReplaceCall(call, min_max);
4340 } 4401 }
4341 } 4402 }
4342 } else if (recognized_kind == MethodRecognizer::kMathDoublePow) { 4403 } else if (recognized_kind == MethodRecognizer::kMathDoublePow) {
4404 if (Compiler::always_optimize()) {
4405 // No UnboxDouble instructons allowed.
4406 return;
4407 }
4343 // We know that first argument is double, the second is num. 4408 // We know that first argument is double, the second is num.
4344 // InvokeMathCFunctionInstr requires unboxed doubles. UnboxDouble 4409 // InvokeMathCFunctionInstr requires unboxed doubles. UnboxDouble
4345 // instructions contain type checks and conversions to double. 4410 // instructions contain type checks and conversions to double.
4346 ZoneGrowableArray<Value*>* args = 4411 ZoneGrowableArray<Value*>* args =
4347 new(Z) ZoneGrowableArray<Value*>(call->ArgumentCount()); 4412 new(Z) ZoneGrowableArray<Value*>(call->ArgumentCount());
4348 for (intptr_t i = 0; i < call->ArgumentCount(); i++) { 4413 for (intptr_t i = 0; i < call->ArgumentCount(); i++) {
4349 args->Add(new(Z) Value(call->ArgumentAt(i))); 4414 args->Add(new(Z) Value(call->ArgumentAt(i)));
4350 } 4415 }
4351 InvokeMathCFunctionInstr* invoke = 4416 InvokeMathCFunctionInstr* invoke =
4352 new(Z) InvokeMathCFunctionInstr(args, 4417 new(Z) InvokeMathCFunctionInstr(args,
(...skipping 4228 matching lines...) Expand 10 before | Expand all | Expand 10 after
8581 8646
8582 // Insert materializations at environment uses. 8647 // Insert materializations at environment uses.
8583 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { 8648 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) {
8584 CreateMaterializationAt( 8649 CreateMaterializationAt(
8585 exits_collector_.exits()[i], alloc, *slots); 8650 exits_collector_.exits()[i], alloc, *slots);
8586 } 8651 }
8587 } 8652 }
8588 8653
8589 8654
8590 } // namespace dart 8655 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698