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

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

Issue 12529008: Collect type feedback for fields. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: address Ivan's comments Created 7 years, 9 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/code_generator.cc ('k') | runtime/vm/flow_graph.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/compiler.h" 5 #include "vm/compiler.h"
6 6
7 #include "vm/assembler.h" 7 #include "vm/assembler.h"
8 8
9 #include "vm/ast_printer.h" 9 #include "vm/ast_printer.h"
10 #include "vm/code_generator.h" 10 #include "vm/code_generator.h"
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 // Transform to SSA (virtual register 0 and no inlining arguments). 160 // Transform to SSA (virtual register 0 and no inlining arguments).
161 flow_graph->ComputeSSA(0, NULL); 161 flow_graph->ComputeSSA(0, NULL);
162 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 162 DEBUG_ASSERT(flow_graph->VerifyUseLists());
163 } 163 }
164 164
165 if (FLAG_print_flow_graph || 165 if (FLAG_print_flow_graph ||
166 (optimized && FLAG_print_flow_graph_optimized)) { 166 (optimized && FLAG_print_flow_graph_optimized)) {
167 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph); 167 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph);
168 } 168 }
169 169
170 const ZoneGrowableArray<Field*>* guarded_fields = NULL;
171
170 if (optimized) { 172 if (optimized) {
171 TimerScope timer(FLAG_compiler_stats, 173 TimerScope timer(FLAG_compiler_stats,
172 &CompilerStats::graphoptimizer_timer, 174 &CompilerStats::graphoptimizer_timer,
173 isolate); 175 isolate);
174 176
175 FlowGraphOptimizer optimizer(flow_graph); 177 FlowGraphOptimizer optimizer(flow_graph);
176 optimizer.ApplyICData(); 178 optimizer.ApplyICData();
177 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 179 DEBUG_ASSERT(flow_graph->VerifyUseLists());
178 180
179 // Optimize (a << b) & c patterns. Must occur before 181 // Optimize (a << b) & c patterns. Must occur before
180 // 'SelectRepresentations' which inserts conversion nodes. 182 // 'SelectRepresentations' which inserts conversion nodes.
181 // TODO(srdjan): Moved before inlining until environment use list can 183 // TODO(srdjan): Moved before inlining until environment use list can
182 // be used to detect when shift-left is outside the scope of bit-and. 184 // be used to detect when shift-left is outside the scope of bit-and.
183 optimizer.TryOptimizeLeftShiftWithBitAndPattern(); 185 optimizer.TryOptimizeLeftShiftWithBitAndPattern();
184 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 186 DEBUG_ASSERT(flow_graph->VerifyUseLists());
185 187
186 // Inlining (mutates the flow graph) 188 // Inlining (mutates the flow graph)
187 if (FLAG_use_inlining) { 189 if (FLAG_use_inlining) {
188 TimerScope timer(FLAG_compiler_stats, 190 TimerScope timer(FLAG_compiler_stats,
189 &CompilerStats::graphinliner_timer); 191 &CompilerStats::graphinliner_timer);
190 FlowGraphInliner inliner(flow_graph); 192 FlowGraphInliner inliner(flow_graph);
191 inliner.Inline(); 193 inliner.Inline();
192 // Use lists are maintained and validated by the inliner. 194 // Use lists are maintained and validated by the inliner.
193 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 195 DEBUG_ASSERT(flow_graph->VerifyUseLists());
194 } 196 }
195 197
198 guarded_fields = flow_graph->FieldDependencies();
199
196 // Propagate types and eliminate more type tests. 200 // Propagate types and eliminate more type tests.
197 if (FLAG_propagate_types) { 201 if (FLAG_propagate_types) {
198 FlowGraphTypePropagator propagator(flow_graph); 202 FlowGraphTypePropagator propagator(flow_graph);
199 propagator.Propagate(); 203 propagator.Propagate();
200 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 204 DEBUG_ASSERT(flow_graph->VerifyUseLists());
201 } 205 }
202 206
203 // Use propagated class-ids to optimize further. 207 // Use propagated class-ids to optimize further.
204 optimizer.ApplyClassIds(); 208 optimizer.ApplyClassIds();
205 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 209 DEBUG_ASSERT(flow_graph->VerifyUseLists());
206 210
207 // Do optimizations that depend on the propagated type information. 211 // Do optimizations that depend on the propagated type information.
208 optimizer.Canonicalize(); 212 optimizer.Canonicalize();
209 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 213 DEBUG_ASSERT(flow_graph->VerifyUseLists());
210 214
211 BranchSimplifier::Simplify(flow_graph); 215 BranchSimplifier::Simplify(flow_graph);
212 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 216 DEBUG_ASSERT(flow_graph->VerifyUseLists());
213 217
214 if (FLAG_constant_propagation) { 218 if (FLAG_constant_propagation) {
215 ConstantPropagator::Optimize(flow_graph); 219 ConstantPropagator::Optimize(flow_graph);
216 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 220 DEBUG_ASSERT(flow_graph->VerifyUseLists());
217 // A canonicalization pass to remove e.g. smi checks on smi constants. 221 // A canonicalization pass to remove e.g. smi checks on smi constants.
218 optimizer.Canonicalize(); 222 optimizer.Canonicalize();
219 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 223 DEBUG_ASSERT(flow_graph->VerifyUseLists());
220 } 224 }
221 225
222 // Propagate types and eliminate even more type tests. 226 // Propagate types and eliminate even more type tests.
223 if (FLAG_propagate_types) { 227 if (FLAG_propagate_types) {
228 // Recompute types after constant propagation to infer more precise
229 // types for uses that were previously reached by now eliminated phis.
224 FlowGraphTypePropagator propagator(flow_graph); 230 FlowGraphTypePropagator propagator(flow_graph);
225 propagator.Propagate(); 231 propagator.Propagate();
226 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 232 DEBUG_ASSERT(flow_graph->VerifyUseLists());
227 } 233 }
228 234
229 // Unbox doubles. Performed after constant propagation to minimize 235 // Unbox doubles. Performed after constant propagation to minimize
230 // interference from phis merging double values and tagged 236 // interference from phis merging double values and tagged
231 // values comming from dead paths. 237 // values comming from dead paths.
232 optimizer.SelectRepresentations(); 238 optimizer.SelectRepresentations();
233 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 239 DEBUG_ASSERT(flow_graph->VerifyUseLists());
(...skipping 18 matching lines...) Expand all
252 258
253 if (FLAG_range_analysis) { 259 if (FLAG_range_analysis) {
254 // We have to perform range analysis after LICM because it 260 // We have to perform range analysis after LICM because it
255 // optimistically moves CheckSmi through phis into loop preheaders 261 // optimistically moves CheckSmi through phis into loop preheaders
256 // making some phis smi. 262 // making some phis smi.
257 optimizer.InferSmiRanges(); 263 optimizer.InferSmiRanges();
258 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 264 DEBUG_ASSERT(flow_graph->VerifyUseLists());
259 } 265 }
260 266
261 // The final canonicalization pass before the code generation. 267 // The final canonicalization pass before the code generation.
268 if (FLAG_propagate_types) {
269 // Propagate types one more time after code movement phases.
270 // This recomputes types of values that became dominated by
271 // hoisted checks.
272 FlowGraphTypePropagator propagator(flow_graph);
273 propagator.Propagate();
274 DEBUG_ASSERT(flow_graph->VerifyUseLists());
275 }
262 optimizer.Canonicalize(); 276 optimizer.Canonicalize();
263 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 277 DEBUG_ASSERT(flow_graph->VerifyUseLists());
264 278
265 // Perform register allocation on the SSA graph. 279 // Perform register allocation on the SSA graph.
266 FlowGraphAllocator allocator(*flow_graph); 280 FlowGraphAllocator allocator(*flow_graph);
267 allocator.AllocateRegisters(); 281 allocator.AllocateRegisters();
268 282
269 if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) { 283 if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) {
270 FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph); 284 FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph);
271 } 285 }
(...skipping 17 matching lines...) Expand all
289 const Code& code = Code::Handle( 303 const Code& code = Code::Handle(
290 Code::FinalizeCode(function, &assembler, optimized)); 304 Code::FinalizeCode(function, &assembler, optimized));
291 code.set_is_optimized(optimized); 305 code.set_is_optimized(optimized);
292 graph_compiler.FinalizePcDescriptors(code); 306 graph_compiler.FinalizePcDescriptors(code);
293 graph_compiler.FinalizeDeoptInfo(code); 307 graph_compiler.FinalizeDeoptInfo(code);
294 graph_compiler.FinalizeStackmaps(code); 308 graph_compiler.FinalizeStackmaps(code);
295 graph_compiler.FinalizeVarDescriptors(code); 309 graph_compiler.FinalizeVarDescriptors(code);
296 graph_compiler.FinalizeExceptionHandlers(code); 310 graph_compiler.FinalizeExceptionHandlers(code);
297 graph_compiler.FinalizeComments(code); 311 graph_compiler.FinalizeComments(code);
298 graph_compiler.FinalizeStaticCallTargetsTable(code); 312 graph_compiler.FinalizeStaticCallTargetsTable(code);
313
299 if (optimized) { 314 if (optimized) {
300 CodePatcher::PatchEntry(Code::Handle(function.CurrentCode())); 315 CodePatcher::PatchEntry(Code::Handle(function.CurrentCode()));
301 function.SetCode(code); 316 function.SetCode(code);
302 if (FLAG_trace_compiler) { 317 if (FLAG_trace_compiler) {
303 OS::Print("--> patching entry %#"Px"\n", 318 OS::Print("--> patching entry %#"Px"\n",
304 Code::Handle(function.unoptimized_code()).EntryPoint()); 319 Code::Handle(function.unoptimized_code()).EntryPoint());
305 } 320 }
321
322 for (intptr_t i = 0; i < guarded_fields->length(); i++) {
323 const Field& field = *(*guarded_fields)[i];
324 field.RegisterDependentCode(code);
325 }
306 } else { 326 } else {
307 function.set_unoptimized_code(code); 327 function.set_unoptimized_code(code);
308 function.SetCode(code); 328 function.SetCode(code);
309 ASSERT(CodePatcher::CodeIsPatchable(code)); 329 ASSERT(CodePatcher::CodeIsPatchable(code));
310 } 330 }
311 } 331 }
312 is_compiled = true; 332 is_compiled = true;
313 } else { 333 } else {
314 // We bailed out. 334 // We bailed out.
315 Error& bailout_error = Error::Handle( 335 Error& bailout_error = Error::Handle(
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 Object::Handle(isolate->object_store()->sticky_error()); 681 Object::Handle(isolate->object_store()->sticky_error());
662 isolate->object_store()->clear_sticky_error(); 682 isolate->object_store()->clear_sticky_error();
663 isolate->set_long_jump_base(base); 683 isolate->set_long_jump_base(base);
664 return result.raw(); 684 return result.raw();
665 } 685 }
666 UNREACHABLE(); 686 UNREACHABLE();
667 return Object::null(); 687 return Object::null();
668 } 688 }
669 689
670 } // namespace dart 690 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/code_generator.cc ('k') | runtime/vm/flow_graph.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698