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

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

Issue 3003593002: [vm] Cleanup Instruction::Effects(), prepare to cleanup Dependencies() (Closed)
Patch Set: TODO comment corrected Created 3 years, 4 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
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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/redundancy_elimination.h" 5 #include "vm/redundancy_elimination.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/flow_graph.h" 8 #include "vm/flow_graph.h"
9 #include "vm/hash_map.h" 9 #include "vm/hash_map.h"
10 #include "vm/il_printer.h" 10 #include "vm/il_printer.h"
11 #include "vm/intermediate_language.h" 11 #include "vm/intermediate_language.h"
12 #include "vm/stack_frame.h" 12 #include "vm/stack_frame.h"
13 13
14 namespace dart { 14 namespace dart {
15 15
16 DEFINE_FLAG(bool, dead_store_elimination, true, "Eliminate dead stores"); 16 DEFINE_FLAG(bool, dead_store_elimination, true, "Eliminate dead stores");
17 DEFINE_FLAG(bool, load_cse, true, "Use redundant load elimination."); 17 DEFINE_FLAG(bool, load_cse, true, "Use redundant load elimination.");
18 DEFINE_FLAG(bool, 18 DEFINE_FLAG(bool,
19 trace_load_optimization, 19 trace_load_optimization,
20 false, 20 false,
21 "Print live sets for load optimization pass."); 21 "Print live sets for load optimization pass.");
22 22
23 // Quick access to the current zone. 23 // Quick access to the current zone.
24 #define Z (zone()) 24 #define Z (zone())
25 25
26 class CSEInstructionMap : public ValueObject { 26 class CSEInstructionMap : public ValueObject {
27 public: 27 public:
28 // Right now CSE and LICM track a single effect which is no longer used. 28 CSEInstructionMap() : map_() {}
29 // TODO(alexmarkov): cleanup. 29 explicit CSEInstructionMap(const CSEInstructionMap& other)
30 // Other effects like modifications of fields are tracked in a separate load 30 : ValueObject(), map_(other.map_) {}
31 // forwarding pass via Alias structure.
32 COMPILE_ASSERT(EffectSet::kLastEffect == 1);
33 31
34 CSEInstructionMap() : independent_(), dependent_() {} 32 Instruction* Lookup(Instruction* other) const {
35 explicit CSEInstructionMap(const CSEInstructionMap& other) 33 ASSERT(other->AllowsCSE());
36 : ValueObject(), 34 ASSERT(other->Dependencies().IsNone());
37 independent_(other.independent_), 35 return map_.LookupValue(other);
38 dependent_(other.dependent_) {}
39
40 void RemoveAffected(EffectSet effects) {
41 if (!effects.IsNone()) {
42 dependent_.Clear();
43 }
44 } 36 }
45 37
46 Instruction* Lookup(Instruction* other) const { 38 void Insert(Instruction* instr) {
47 return GetMapFor(other)->LookupValue(other); 39 ASSERT(instr->AllowsCSE());
40 ASSERT(instr->Dependencies().IsNone());
41 return map_.Insert(instr);
48 } 42 }
49 43
50 void Insert(Instruction* instr) { return GetMapFor(instr)->Insert(instr); }
51
52 private: 44 private:
53 typedef DirectChainedHashMap<PointerKeyValueTrait<Instruction> > Map; 45 typedef DirectChainedHashMap<PointerKeyValueTrait<Instruction> > Map;
54 46
55 Map* GetMapFor(Instruction* instr) { 47 Map map_;
56 return instr->Dependencies().IsNone() ? &independent_ : &dependent_;
57 }
58
59 const Map* GetMapFor(Instruction* instr) const {
60 return instr->Dependencies().IsNone() ? &independent_ : &dependent_;
61 }
62
63 // All computations that are not affected by any side-effect.
64 // Majority of computations are not affected by anything and will be in
65 // this map.
66 Map independent_;
67
68 // All computations that are affected by side effect.
69 Map dependent_;
70 }; 48 };
71 49
72 // Place describes an abstract location (e.g. field) that IR can load 50 // Place describes an abstract location (e.g. field) that IR can load
73 // from or store to. 51 // from or store to.
74 // 52 //
75 // Places are also used to describe wild-card locations also known as aliases, 53 // Places are also used to describe wild-card locations also known as aliases,
76 // that essentially represent sets of places that alias each other. Places A 54 // that essentially represent sets of places that alias each other. Places A
77 // and B are said to alias each other if store into A can affect load from B. 55 // and B are said to alias each other if store into A can affect load from B.
78 // 56 //
79 // We distinguish the following aliases: 57 // We distinguish the following aliases:
(...skipping 1510 matching lines...) Expand 10 before | Expand all | Expand 10 after
1590 // Check if this load needs renumbering because of the intrablock 1568 // Check if this load needs renumbering because of the intrablock
1591 // load forwarding. 1569 // load forwarding.
1592 const Place* canonical = aliased_set_->LookupCanonical(&place); 1570 const Place* canonical = aliased_set_->LookupCanonical(&place);
1593 if ((canonical != NULL) && 1571 if ((canonical != NULL) &&
1594 (canonical->id() != instr->AsDefinition()->place_id())) { 1572 (canonical->id() != instr->AsDefinition()->place_id())) {
1595 instr->AsDefinition()->set_place_id(canonical->id()); 1573 instr->AsDefinition()->set_place_id(canonical->id());
1596 } 1574 }
1597 } 1575 }
1598 1576
1599 // If instruction has effects then kill all loads affected. 1577 // If instruction has effects then kill all loads affected.
1600 if (!instr->Effects().IsNone()) { 1578 if (instr->HasSideEffects()) {
1601 kill->AddAll(aliased_set_->aliased_by_effects()); 1579 kill->AddAll(aliased_set_->aliased_by_effects());
1602 // There is no need to clear out_values when removing values from GEN 1580 // There is no need to clear out_values when removing values from GEN
1603 // set because only those values that are in the GEN set 1581 // set because only those values that are in the GEN set
1604 // will ever be used. 1582 // will ever be used.
1605 gen->RemoveAll(aliased_set_->aliased_by_effects()); 1583 gen->RemoveAll(aliased_set_->aliased_by_effects());
1606 continue; 1584 continue;
1607 } 1585 }
1608 1586
1609 Definition* defn = instr->AsDefinition(); 1587 Definition* defn = instr->AsDefinition();
1610 if (defn == NULL) { 1588 if (defn == NULL) {
(...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after
2349 } 2327 }
2350 2328
2351 bool DominatorBasedCSE::OptimizeRecursive(FlowGraph* graph, 2329 bool DominatorBasedCSE::OptimizeRecursive(FlowGraph* graph,
2352 BlockEntryInstr* block, 2330 BlockEntryInstr* block,
2353 CSEInstructionMap* map) { 2331 CSEInstructionMap* map) {
2354 bool changed = false; 2332 bool changed = false;
2355 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { 2333 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
2356 Instruction* current = it.Current(); 2334 Instruction* current = it.Current();
2357 if (current->AllowsCSE()) { 2335 if (current->AllowsCSE()) {
2358 Instruction* replacement = map->Lookup(current); 2336 Instruction* replacement = map->Lookup(current);
2337 ASSERT((replacement == NULL) || replacement->AllowsCSE());
2359 if ((replacement != NULL) && 2338 if ((replacement != NULL) &&
2360 graph->block_effects()->IsAvailableAt(replacement, block)) { 2339 graph->block_effects()->IsAvailableAt(replacement, block)) {
2361 // Replace current with lookup result. 2340 // Replace current with lookup result.
2362 graph->ReplaceCurrentInstruction(&it, current, replacement); 2341 graph->ReplaceCurrentInstruction(&it, current, replacement);
2363 changed = true; 2342 changed = true;
2364 continue; 2343 continue;
2365 } 2344 }
2366 2345
2367 // For simplicity we assume that instruction either does not depend on 2346 // For simplicity we assume that instruction either does not depend on
2368 // anything or does not affect anything. If this is not the case then 2347 // anything or does not affect anything. If this is not the case then
2369 // we should first remove affected instructions from the map and 2348 // we should first remove affected instructions from the map and
2370 // then add instruction to the map so that it does not kill itself. 2349 // then add instruction to the map so that it does not kill itself.
2371 ASSERT(current->Effects().IsNone() || current->Dependencies().IsNone()); 2350 ASSERT(!current->HasSideEffects() || current->Dependencies().IsNone());
2372 map->Insert(current); 2351 map->Insert(current);
2373 } 2352 }
2374
2375 map->RemoveAffected(current->Effects());
2376 } 2353 }
2377 2354
2378 // Process children in the dominator tree recursively. 2355 // Process children in the dominator tree recursively.
2379 intptr_t num_children = block->dominated_blocks().length(); 2356 intptr_t num_children = block->dominated_blocks().length();
2380 if (num_children != 0) { 2357 if (num_children != 0) {
2381 graph->thread()->CheckForSafepoint(); 2358 graph->thread()->CheckForSafepoint();
2382 } 2359 }
2383 for (intptr_t i = 0; i < num_children; ++i) { 2360 for (intptr_t i = 0; i < num_children; ++i) {
2384 BlockEntryInstr* child = block->dominated_blocks()[i]; 2361 BlockEntryInstr* child = block->dominated_blocks()[i];
2385 if (i < num_children - 1) { 2362 if (i < num_children - 1) {
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
2512 } 2489 }
2513 exposed_stores->Add(instr); 2490 exposed_stores->Add(instr);
2514 } 2491 }
2515 // Interfering stores kill only loads from the same place. 2492 // Interfering stores kill only loads from the same place.
2516 kill->Add(instr->place_id()); 2493 kill->Add(instr->place_id());
2517 live_in->Remove(instr->place_id()); 2494 live_in->Remove(instr->place_id());
2518 continue; 2495 continue;
2519 } 2496 }
2520 2497
2521 // Handle side effects, deoptimization and function return. 2498 // Handle side effects, deoptimization and function return.
2522 if (!instr->Effects().IsNone() || instr->CanDeoptimize() || 2499 if (instr->HasSideEffects() || instr->CanDeoptimize() ||
2523 instr->IsThrow() || instr->IsReThrow() || instr->IsReturn()) { 2500 instr->IsThrow() || instr->IsReThrow() || instr->IsReturn()) {
2524 // Instructions that return from the function, instructions with side 2501 // Instructions that return from the function, instructions with side
2525 // effects and instructions that can deoptimize are considered as 2502 // effects and instructions that can deoptimize are considered as
2526 // loads from all places. 2503 // loads from all places.
2527 live_in->CopyFrom(all_places); 2504 live_in->CopyFrom(all_places);
2528 if (instr->IsThrow() || instr->IsReThrow() || instr->IsReturn()) { 2505 if (instr->IsThrow() || instr->IsReThrow() || instr->IsReturn()) {
2529 // Initialize live-out for exit blocks since it won't be computed 2506 // Initialize live-out for exit blocks since it won't be computed
2530 // otherwise during the fixed point iteration. 2507 // otherwise during the fixed point iteration.
2531 live_out->CopyFrom(all_places); 2508 live_out->CopyFrom(all_places);
2532 } 2509 }
(...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after
3327 if (to_index == 0) { 3304 if (to_index == 0) {
3328 join->phis_ = NULL; 3305 join->phis_ = NULL;
3329 } else { 3306 } else {
3330 join->phis_->TruncateTo(to_index); 3307 join->phis_->TruncateTo(to_index);
3331 } 3308 }
3332 } 3309 }
3333 } 3310 }
3334 } 3311 }
3335 3312
3336 } // namespace dart 3313 } // namespace dart
OLDNEW
« runtime/vm/intermediate_language.h ('K') | « runtime/vm/intermediate_language.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698