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

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

Issue 11187046: Apply optimization after class-id propagation: instance calls without ICData are optimized by using… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 2 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 | Annotate | Revision Log
« 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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/flow_graph_builder.h" 9 #include "vm/flow_graph_builder.h"
10 #include "vm/flow_graph_compiler.h" 10 #include "vm/flow_graph_compiler.h"
11 #include "vm/hash_map.h" 11 #include "vm/hash_map.h"
12 #include "vm/il_printer.h" 12 #include "vm/il_printer.h"
13 #include "vm/intermediate_language.h" 13 #include "vm/intermediate_language.h"
14 #include "vm/object_store.h" 14 #include "vm/object_store.h"
15 #include "vm/parser.h" 15 #include "vm/parser.h"
16 #include "vm/resolver.h"
16 #include "vm/scopes.h" 17 #include "vm/scopes.h"
17 #include "vm/symbols.h" 18 #include "vm/symbols.h"
18 19
19 namespace dart { 20 namespace dart {
20 21
21 DECLARE_FLAG(bool, eliminate_type_checks); 22 DECLARE_FLAG(bool, eliminate_type_checks);
22 DECLARE_FLAG(bool, enable_type_checks); 23 DECLARE_FLAG(bool, enable_type_checks);
23 DEFINE_FLAG(bool, trace_optimization, false, "Print optimization details."); 24 DEFINE_FLAG(bool, trace_optimization, false, "Print optimization details.");
24 DECLARE_FLAG(bool, trace_type_check_elimination); 25 DECLARE_FLAG(bool, trace_type_check_elimination);
25 DEFINE_FLAG(bool, use_cha, true, "Use class hierarchy analysis."); 26 DEFINE_FLAG(bool, use_cha, true, "Use class hierarchy analysis.");
26 DEFINE_FLAG(bool, load_cse, true, "Use redundant load elimination."); 27 DEFINE_FLAG(bool, load_cse, true, "Use redundant load elimination.");
27 DEFINE_FLAG(bool, trace_range_analysis, false, "Trace range analysis progress"); 28 DEFINE_FLAG(bool, trace_range_analysis, false, "Trace range analysis progress");
28 DEFINE_FLAG(bool, trace_constant_propagation, false, 29 DEFINE_FLAG(bool, trace_constant_propagation, false,
29 "Print constant propagation and useless code elimination."); 30 "Print constant propagation and useless code elimination.");
30 31
32
31 void FlowGraphOptimizer::ApplyICData() { 33 void FlowGraphOptimizer::ApplyICData() {
32 VisitBlocks(); 34 VisitBlocks();
33 } 35 }
34 36
35 37
38 // Attempts to convert an instance call (IC call) using propagated class-ids,
39 // e.g., receiver class id.
40 void FlowGraphOptimizer::ApplyClassIds() {
41 ASSERT(current_iterator_ == NULL);
42 for (intptr_t i = 0; i < block_order_.length(); ++i) {
43 BlockEntryInstr* entry = block_order_[i];
44 ForwardInstructionIterator it(entry);
45 current_iterator_ = &it;
46 for (; !it.Done(); it.Advance()) {
47 if (it.Current()->IsInstanceCall()) {
48 InstanceCallInstr* call = it.Current()->AsInstanceCall();
49 if (call->HasICData()) {
50 if (TryCreateICData(call)) {
51 VisitInstanceCall(call);
52 }
53 }
54 }
55 }
56 current_iterator_ = NULL;
57 }
58 }
59
60
61 // Attempt to build ICData for call using propagated class-ids.
62 bool FlowGraphOptimizer::TryCreateICData(InstanceCallInstr* call) {
63 ASSERT(call->HasICData());
64 if (call->ic_data()->NumberOfChecks() > 0) {
65 // This occurs when an instance call has too many checks.
66 // TODO(srdjan): Replace IC call with megamorphic call.
67 return false;
68 }
69 GrowableArray<intptr_t> class_ids(call->ic_data()->num_args_tested());
70 ASSERT(call->ic_data()->num_args_tested() <= call->ArgumentCount());
71 for (intptr_t i = 0; i < call->ic_data()->num_args_tested(); i++) {
72 intptr_t cid = call->ArgumentAt(i)->value()->ResultCid();
73 class_ids.Add(cid);
74 }
75 // TODO(srdjan): Test for other class_ids > 1.
76 if (class_ids.length() != 1) return false;
77 if (class_ids[0] != kDynamicCid) {
78 const intptr_t num_named_arguments = call->argument_names().IsNull() ?
79 0 : call->argument_names().Length();
80 const Class& receiver_class = Class::Handle(
81 Isolate::Current()->class_table()->At(class_ids[0]));
82 Function& function = Function::Handle();
83 function = Resolver::ResolveDynamicForReceiverClass(
84 receiver_class,
85 call->function_name(),
86 call->ArgumentCount(),
87 num_named_arguments);
88 if (function.IsNull()) {
89 return false;
90 }
91 // Create new ICData, do not modify the one attached to the instruction
92 // since it is attached to the assembly instruction itself.
93 // TODO(srdjan): Prevent modification of ICData object that is
94 // referenced in assembly code.
95 ICData& ic_data = ICData::ZoneHandle(ICData::New(
96 flow_graph_->parsed_function().function(),
97 call->function_name(),
98 call->deopt_id(),
99 class_ids.length()));
100 ic_data.AddReceiverCheck(class_ids[0], function);
101 call->set_ic_data(&ic_data);
102 return true;
103 }
104 return false;
105 }
106
107
36 static void ReplaceCurrentInstruction(ForwardInstructionIterator* it, 108 static void ReplaceCurrentInstruction(ForwardInstructionIterator* it,
37 Instruction* current, 109 Instruction* current,
38 Instruction* replacement) { 110 Instruction* replacement) {
39 if ((replacement != NULL) && current->IsDefinition()) { 111 if ((replacement != NULL) && current->IsDefinition()) {
40 Definition* current_defn = current->AsDefinition(); 112 Definition* current_defn = current->AsDefinition();
41 Definition* replacement_defn = replacement->AsDefinition(); 113 Definition* replacement_defn = replacement->AsDefinition();
42 ASSERT(replacement_defn != NULL); 114 ASSERT(replacement_defn != NULL);
43 current_defn->ReplaceUsesWith(replacement_defn); 115 current_defn->ReplaceUsesWith(replacement_defn);
44 116
45 if (FLAG_trace_optimization) { 117 if (FLAG_trace_optimization) {
(...skipping 1060 matching lines...) Expand 10 before | Expand all | Expand 10 after
1106 call_with_checks = false; 1178 call_with_checks = false;
1107 } else { 1179 } else {
1108 call_with_checks = true; 1180 call_with_checks = true;
1109 } 1181 }
1110 PolymorphicInstanceCallInstr* call = 1182 PolymorphicInstanceCallInstr* call =
1111 new PolymorphicInstanceCallInstr(instr, unary_checks, 1183 new PolymorphicInstanceCallInstr(instr, unary_checks,
1112 call_with_checks); 1184 call_with_checks);
1113 instr->ReplaceWith(call, current_iterator()); 1185 instr->ReplaceWith(call, current_iterator());
1114 } 1186 }
1115 } 1187 }
1116 // An instance call without ICData should continue calling via IC calls 1188 // An instance call without ICData will trigger deoptimization.
1117 // which should trigger reoptimization of optimized code.
1118 } 1189 }
1119 1190
1120 1191
1121 void FlowGraphOptimizer::VisitStaticCall(StaticCallInstr* call) { 1192 void FlowGraphOptimizer::VisitStaticCall(StaticCallInstr* call) {
1122 MethodRecognizer::Kind recognized_kind = 1193 MethodRecognizer::Kind recognized_kind =
1123 MethodRecognizer::RecognizeKind(call->function()); 1194 MethodRecognizer::RecognizeKind(call->function());
1124 if (recognized_kind == MethodRecognizer::kMathSqrt) { 1195 if (recognized_kind == MethodRecognizer::kMathSqrt) {
1125 MathSqrtInstr* sqrt = new MathSqrtInstr(call->ArgumentAt(0)->value(), call); 1196 MathSqrtInstr* sqrt = new MathSqrtInstr(call->ArgumentAt(0)->value(), call);
1126 call->ReplaceWith(sqrt, current_iterator()); 1197 call->ReplaceWith(sqrt, current_iterator());
1127 RemovePushArguments(call); 1198 RemovePushArguments(call);
(...skipping 2264 matching lines...) Expand 10 before | Expand all | Expand 10 after
3392 3463
3393 if (FLAG_trace_constant_propagation) { 3464 if (FLAG_trace_constant_propagation) {
3394 OS::Print("\n==== After constant propagation ====\n"); 3465 OS::Print("\n==== After constant propagation ====\n");
3395 FlowGraphPrinter printer(*graph_); 3466 FlowGraphPrinter printer(*graph_);
3396 printer.PrintBlocks(); 3467 printer.PrintBlocks();
3397 } 3468 }
3398 } 3469 }
3399 3470
3400 3471
3401 } // namespace dart 3472 } // 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