| OLD | NEW |
| 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 #ifndef VM_FLOW_GRAPH_OPTIMIZER_H_ | 5 #ifndef VM_FLOW_GRAPH_OPTIMIZER_H_ |
| 6 #define VM_FLOW_GRAPH_OPTIMIZER_H_ | 6 #define VM_FLOW_GRAPH_OPTIMIZER_H_ |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 #include "vm/flow_graph.h" | 9 #include "vm/flow_graph.h" |
| 10 | 10 |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 FlowGraph* flow_graph_; | 276 FlowGraph* flow_graph_; |
| 277 | 277 |
| 278 const bool use_speculative_inlining_; | 278 const bool use_speculative_inlining_; |
| 279 | 279 |
| 280 GrowableArray<intptr_t>* inlining_black_list_; | 280 GrowableArray<intptr_t>* inlining_black_list_; |
| 281 | 281 |
| 282 DISALLOW_COPY_AND_ASSIGN(FlowGraphOptimizer); | 282 DISALLOW_COPY_AND_ASSIGN(FlowGraphOptimizer); |
| 283 }; | 283 }; |
| 284 | 284 |
| 285 | 285 |
| 286 // Loop invariant code motion. | |
| 287 class LICM : public ValueObject { | |
| 288 public: | |
| 289 explicit LICM(FlowGraph* flow_graph); | |
| 290 | |
| 291 void Optimize(); | |
| 292 | |
| 293 void OptimisticallySpecializeSmiPhis(); | |
| 294 | |
| 295 private: | |
| 296 FlowGraph* flow_graph() const { return flow_graph_; } | |
| 297 | |
| 298 void Hoist(ForwardInstructionIterator* it, | |
| 299 BlockEntryInstr* pre_header, | |
| 300 Instruction* current); | |
| 301 | |
| 302 void TrySpecializeSmiPhi(PhiInstr* phi, | |
| 303 BlockEntryInstr* header, | |
| 304 BlockEntryInstr* pre_header); | |
| 305 | |
| 306 FlowGraph* const flow_graph_; | |
| 307 }; | |
| 308 | |
| 309 | |
| 310 // A simple common subexpression elimination based | |
| 311 // on the dominator tree. | |
| 312 class DominatorBasedCSE : public AllStatic { | |
| 313 public: | |
| 314 // Return true, if the optimization changed the flow graph. | |
| 315 // False, if nothing changed. | |
| 316 static bool Optimize(FlowGraph* graph); | |
| 317 | |
| 318 private: | |
| 319 static bool OptimizeRecursive( | |
| 320 FlowGraph* graph, | |
| 321 BlockEntryInstr* entry, | |
| 322 CSEInstructionMap* map); | |
| 323 }; | |
| 324 | |
| 325 | |
| 326 class DeadStoreElimination : public AllStatic { | |
| 327 public: | |
| 328 static void Optimize(FlowGraph* graph); | |
| 329 }; | |
| 330 | |
| 331 | |
| 332 class DeadCodeElimination : public AllStatic { | |
| 333 public: | |
| 334 static void EliminateDeadPhis(FlowGraph* graph); | |
| 335 }; | |
| 336 | |
| 337 | |
| 338 class AllocationSinking : public ZoneAllocated { | |
| 339 public: | |
| 340 explicit AllocationSinking(FlowGraph* flow_graph) | |
| 341 : flow_graph_(flow_graph), | |
| 342 candidates_(5), | |
| 343 materializations_(5) { } | |
| 344 | |
| 345 const GrowableArray<Definition*>& candidates() const { | |
| 346 return candidates_; | |
| 347 } | |
| 348 | |
| 349 // Find the materialization insterted for the given allocation | |
| 350 // at the given exit. | |
| 351 MaterializeObjectInstr* MaterializationFor(Definition* alloc, | |
| 352 Instruction* exit); | |
| 353 | |
| 354 void Optimize(); | |
| 355 | |
| 356 void DetachMaterializations(); | |
| 357 | |
| 358 private: | |
| 359 // Helper class to collect deoptimization exits that might need to | |
| 360 // rematerialize an object: that is either instructions that reference | |
| 361 // this object explicitly in their deoptimization environment or | |
| 362 // reference some other allocation sinking candidate that points to | |
| 363 // this object. | |
| 364 class ExitsCollector : public ValueObject { | |
| 365 public: | |
| 366 ExitsCollector() : exits_(10), worklist_(3) { } | |
| 367 | |
| 368 const GrowableArray<Instruction*>& exits() const { return exits_; } | |
| 369 | |
| 370 void CollectTransitively(Definition* alloc); | |
| 371 | |
| 372 private: | |
| 373 // Collect immediate uses of this object in the environments. | |
| 374 // If this object is stored into other allocation sinking candidates | |
| 375 // put them onto worklist so that CollectTransitively will process them. | |
| 376 void Collect(Definition* alloc); | |
| 377 | |
| 378 GrowableArray<Instruction*> exits_; | |
| 379 GrowableArray<Definition*> worklist_; | |
| 380 }; | |
| 381 | |
| 382 void CollectCandidates(); | |
| 383 | |
| 384 void NormalizeMaterializations(); | |
| 385 | |
| 386 void RemoveUnusedMaterializations(); | |
| 387 | |
| 388 void DiscoverFailedCandidates(); | |
| 389 | |
| 390 void InsertMaterializations(Definition* alloc); | |
| 391 | |
| 392 void CreateMaterializationAt( | |
| 393 Instruction* exit, | |
| 394 Definition* alloc, | |
| 395 const ZoneGrowableArray<const Object*>& fields); | |
| 396 | |
| 397 void EliminateAllocation(Definition* alloc); | |
| 398 | |
| 399 Isolate* isolate() const { return flow_graph_->isolate(); } | |
| 400 Zone* zone() const { return flow_graph_->zone(); } | |
| 401 | |
| 402 FlowGraph* flow_graph_; | |
| 403 | |
| 404 GrowableArray<Definition*> candidates_; | |
| 405 GrowableArray<MaterializeObjectInstr*> materializations_; | |
| 406 | |
| 407 ExitsCollector exits_collector_; | |
| 408 }; | |
| 409 | |
| 410 | |
| 411 // Optimize spill stores inside try-blocks by identifying values that always | |
| 412 // contain a single known constant at catch block entry. | |
| 413 class TryCatchAnalyzer : public AllStatic { | |
| 414 public: | |
| 415 static void Optimize(FlowGraph* flow_graph); | |
| 416 }; | |
| 417 | |
| 418 } // namespace dart | 286 } // namespace dart |
| 419 | 287 |
| 420 #endif // VM_FLOW_GRAPH_OPTIMIZER_H_ | 288 #endif // VM_FLOW_GRAPH_OPTIMIZER_H_ |
| OLD | NEW |