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

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

Issue 1497783002: Fix optimizations on static fields in precompiled code. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: addressed comment Created 5 years 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/constant_propagator.cc ('k') | runtime/vm/flow_graph_type_propagator.cc » ('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/compiler.h"
10 #include "vm/cpu.h" 10 #include "vm/cpu.h"
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 #if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_IA32) 48 #if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_IA32)
49 DEFINE_FLAG(bool, trace_smi_widening, false, "Trace Smi->Int32 widening pass."); 49 DEFINE_FLAG(bool, trace_smi_widening, false, "Trace Smi->Int32 widening pass.");
50 #endif 50 #endif
51 51
52 DECLARE_FLAG(bool, polymorphic_with_deopt); 52 DECLARE_FLAG(bool, polymorphic_with_deopt);
53 DECLARE_FLAG(bool, source_lines); 53 DECLARE_FLAG(bool, source_lines);
54 DECLARE_FLAG(bool, trace_cha); 54 DECLARE_FLAG(bool, trace_cha);
55 DECLARE_FLAG(bool, trace_field_guards); 55 DECLARE_FLAG(bool, trace_field_guards);
56 DECLARE_FLAG(bool, trace_type_check_elimination); 56 DECLARE_FLAG(bool, trace_type_check_elimination);
57 DECLARE_FLAG(bool, warn_on_javascript_compatibility); 57 DECLARE_FLAG(bool, warn_on_javascript_compatibility);
58 DECLARE_FLAG(bool, fields_may_be_reset);
58 59
59 // Quick access to the current isolate and zone. 60 // Quick access to the current isolate and zone.
60 #define I (isolate()) 61 #define I (isolate())
61 #define Z (zone()) 62 #define Z (zone())
62 63
63 static bool ShouldInlineSimd() { 64 static bool ShouldInlineSimd() {
64 return FlowGraphCompiler::SupportsUnboxedSimd128(); 65 return FlowGraphCompiler::SupportsUnboxedSimd128();
65 } 66 }
66 67
67 68
(...skipping 5578 matching lines...) Expand 10 before | Expand all | Expand 10 after
5646 "<%s[%" Pd "|%" Pd "]>", 5647 "<%s[%" Pd "|%" Pd "]>",
5647 DefinitionName(instance()), 5648 DefinitionName(instance()),
5648 index_constant(), 5649 index_constant(),
5649 ElementSizeMultiplier(element_size())); 5650 ElementSizeMultiplier(element_size()));
5650 } 5651 }
5651 } 5652 }
5652 UNREACHABLE(); 5653 UNREACHABLE();
5653 return "<?>"; 5654 return "<?>";
5654 } 5655 }
5655 5656
5656 bool IsFinalField() const { 5657 // Fields that are considered immutable by load optimization.
5657 return (kind() == kField) && field().is_final(); 5658 // Handle static finals as non-final with precompilation because
5659 // they may be reset to uninitialized after compilation.
5660 bool IsImmutableField() const {
5661 return (kind() == kField)
5662 && field().is_final()
5663 && (!field().is_static() || !FLAG_fields_may_be_reset);
5658 } 5664 }
5659 5665
5660 intptr_t Hashcode() const { 5666 intptr_t Hashcode() const {
5661 return (flags_ * 63 + reinterpret_cast<intptr_t>(instance_)) * 31 + 5667 return (flags_ * 63 + reinterpret_cast<intptr_t>(instance_)) * 31 +
5662 FieldHashcode(); 5668 FieldHashcode();
5663 } 5669 }
5664 5670
5665 bool Equals(const Place* other) const { 5671 bool Equals(const Place* other) const {
5666 return (flags_ == other->flags_) && 5672 return (flags_ == other->flags_) &&
5667 (instance_ == other->instance_) && 5673 (instance_ == other->instance_) &&
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
5984 // Artificial alias that is used to collect all representatives of 5990 // Artificial alias that is used to collect all representatives of
5985 // X[*] alias for all X. 5991 // X[*] alias for all X.
5986 kAnyAllocationIndexedAlias = 3, 5992 kAnyAllocationIndexedAlias = 3,
5987 5993
5988 // *[*] alias. 5994 // *[*] alias.
5989 kAnyInstanceAnyIndexAlias = 4 5995 kAnyInstanceAnyIndexAlias = 4
5990 }; 5996 };
5991 5997
5992 // Compute least generic alias for the place and assign alias id to it. 5998 // Compute least generic alias for the place and assign alias id to it.
5993 void AddRepresentative(Place* place) { 5999 void AddRepresentative(Place* place) {
5994 if (!place->IsFinalField()) { 6000 if (!place->IsImmutableField()) {
5995 const Place* alias = CanonicalizeAlias(place->ToAlias()); 6001 const Place* alias = CanonicalizeAlias(place->ToAlias());
5996 EnsureSet(&representatives_, alias->id())->Add(place->id()); 6002 EnsureSet(&representatives_, alias->id())->Add(place->id());
5997 6003
5998 // Update cumulative representative sets that are used during 6004 // Update cumulative representative sets that are used during
5999 // killed sets computation. 6005 // killed sets computation.
6000 if (alias->kind() == Place::kConstantIndexed) { 6006 if (alias->kind() == Place::kConstantIndexed) {
6001 if (CanBeAliased(alias->instance())) { 6007 if (CanBeAliased(alias->instance())) {
6002 EnsureSet(&representatives_, kAnyConstantIndexedAlias)-> 6008 EnsureSet(&representatives_, kAnyConstantIndexedAlias)->
6003 Add(place->id()); 6009 Add(place->id());
6004 } 6010 }
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
6190 6196
6191 case Place::kNone: 6197 case Place::kNone:
6192 UNREACHABLE(); 6198 UNREACHABLE();
6193 } 6199 }
6194 } 6200 }
6195 6201
6196 // Returns true if the given load is unaffected by external side-effects. 6202 // Returns true if the given load is unaffected by external side-effects.
6197 // This essentially means that no stores to the same location can 6203 // This essentially means that no stores to the same location can
6198 // occur in other functions. 6204 // occur in other functions.
6199 bool IsIndependentFromEffects(Place* place) { 6205 bool IsIndependentFromEffects(Place* place) {
6200 if (place->IsFinalField()) { 6206 if (place->IsImmutableField()) {
6201 // Note that we can't use LoadField's is_immutable attribute here because 6207 // Note that we can't use LoadField's is_immutable attribute here because
6202 // some VM-fields (those that have no corresponding Field object and 6208 // some VM-fields (those that have no corresponding Field object and
6203 // accessed through offset alone) can share offset but have different 6209 // accessed through offset alone) can share offset but have different
6204 // immutability properties. 6210 // immutability properties.
6205 // One example is the length property of growable and fixed size list. If 6211 // One example is the length property of growable and fixed size list. If
6206 // loads of these two properties occur in the same function for the same 6212 // loads of these two properties occur in the same function for the same
6207 // receiver then they will get the same expression number. However 6213 // receiver then they will get the same expression number. However
6208 // immutability of the length of fixed size list does not mean that 6214 // immutability of the length of fixed size list does not mean that
6209 // growable list also has immutable property. Thus we will make a 6215 // growable list also has immutable property. Thus we will make a
6210 // conservative assumption for the VM-properties. 6216 // conservative assumption for the VM-properties.
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
6624 6630
6625 bool is_load = false, is_store = false; 6631 bool is_load = false, is_store = false;
6626 Place place(instr, &is_load, &is_store); 6632 Place place(instr, &is_load, &is_store);
6627 6633
6628 BitVector* killed = NULL; 6634 BitVector* killed = NULL;
6629 if (is_store) { 6635 if (is_store) {
6630 const intptr_t alias_id = 6636 const intptr_t alias_id =
6631 aliased_set_->LookupAliasId(place.ToAlias()); 6637 aliased_set_->LookupAliasId(place.ToAlias());
6632 if (alias_id != AliasedSet::kNoAlias) { 6638 if (alias_id != AliasedSet::kNoAlias) {
6633 killed = aliased_set_->GetKilledSet(alias_id); 6639 killed = aliased_set_->GetKilledSet(alias_id);
6634 } else if (!place.IsFinalField()) { 6640 } else if (!place.IsImmutableField()) {
6635 // We encountered unknown alias: this means intrablock load 6641 // We encountered unknown alias: this means intrablock load
6636 // forwarding refined parameter of this store, for example 6642 // forwarding refined parameter of this store, for example
6637 // 6643 //
6638 // o <- alloc() 6644 // o <- alloc()
6639 // a.f <- o 6645 // a.f <- o
6640 // u <- a.f 6646 // u <- a.f
6641 // u.x <- null ;; this store alias is *.x 6647 // u.x <- null ;; this store alias is *.x
6642 // 6648 //
6643 // after intrablock load forwarding 6649 // after intrablock load forwarding
6644 // 6650 //
(...skipping 883 matching lines...) Expand 10 before | Expand all | Expand 10 after
7528 7534
7529 // Iterate backwards starting at the last instruction. 7535 // Iterate backwards starting at the last instruction.
7530 for (BackwardInstructionIterator instr_it(block); 7536 for (BackwardInstructionIterator instr_it(block);
7531 !instr_it.Done(); 7537 !instr_it.Done();
7532 instr_it.Advance()) { 7538 instr_it.Advance()) {
7533 Instruction* instr = instr_it.Current(); 7539 Instruction* instr = instr_it.Current();
7534 7540
7535 bool is_load = false; 7541 bool is_load = false;
7536 bool is_store = false; 7542 bool is_store = false;
7537 Place place(instr, &is_load, &is_store); 7543 Place place(instr, &is_load, &is_store);
7538 if (place.IsFinalField()) { 7544 if (place.IsImmutableField()) {
7539 // Loads/stores of final fields do not participate. 7545 // Loads/stores of final fields do not participate.
7540 continue; 7546 continue;
7541 } 7547 }
7542 7548
7543 // Handle stores. 7549 // Handle stores.
7544 if (is_store) { 7550 if (is_store) {
7545 if (kill->Contains(instr->place_id())) { 7551 if (kill->Contains(instr->place_id())) {
7546 if (!live_in->Contains(instr->place_id()) && 7552 if (!live_in->Contains(instr->place_id()) &&
7547 CanEliminateStore(instr)) { 7553 CanEliminateStore(instr)) {
7548 if (FLAG_trace_optimization) { 7554 if (FLAG_trace_optimization) {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
7617 exposed_stores_[postorder_number]; 7623 exposed_stores_[postorder_number];
7618 if (exposed_stores == NULL) continue; // No exposed stores. 7624 if (exposed_stores == NULL) continue; // No exposed stores.
7619 7625
7620 // Iterate over candidate stores. 7626 // Iterate over candidate stores.
7621 for (intptr_t i = 0; i < exposed_stores->length(); ++i) { 7627 for (intptr_t i = 0; i < exposed_stores->length(); ++i) {
7622 Instruction* instr = (*exposed_stores)[i]; 7628 Instruction* instr = (*exposed_stores)[i];
7623 bool is_load = false; 7629 bool is_load = false;
7624 bool is_store = false; 7630 bool is_store = false;
7625 Place place(instr, &is_load, &is_store); 7631 Place place(instr, &is_load, &is_store);
7626 ASSERT(!is_load && is_store); 7632 ASSERT(!is_load && is_store);
7627 if (place.IsFinalField()) { 7633 if (place.IsImmutableField()) {
7628 // Final field do not participate in dead store elimination. 7634 // Final field do not participate in dead store elimination.
7629 continue; 7635 continue;
7630 } 7636 }
7631 // Eliminate a downward exposed store if the corresponding place is not 7637 // Eliminate a downward exposed store if the corresponding place is not
7632 // in live-out. 7638 // in live-out.
7633 if (!live_out->Contains(instr->place_id()) && 7639 if (!live_out->Contains(instr->place_id()) &&
7634 CanEliminateStore(instr)) { 7640 CanEliminateStore(instr)) {
7635 if (FLAG_trace_optimization) { 7641 if (FLAG_trace_optimization) {
7636 THR_Print("Removing dead store to place %" Pd " block B%" Pd "\n", 7642 THR_Print("Removing dead store to place %" Pd " block B%" Pd "\n",
7637 instr->place_id(), block->block_id()); 7643 instr->place_id(), block->block_id());
(...skipping 1187 matching lines...) Expand 10 before | Expand all | Expand 10 after
8825 8831
8826 // Insert materializations at environment uses. 8832 // Insert materializations at environment uses.
8827 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { 8833 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) {
8828 CreateMaterializationAt( 8834 CreateMaterializationAt(
8829 exits_collector_.exits()[i], alloc, *slots); 8835 exits_collector_.exits()[i], alloc, *slots);
8830 } 8836 }
8831 } 8837 }
8832 8838
8833 8839
8834 } // namespace dart 8840 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/constant_propagator.cc ('k') | runtime/vm/flow_graph_type_propagator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698