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

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

Issue 678763004: Make CTX allocatable by the register allocator. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 1 month 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
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/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 5122 matching lines...) Expand 10 before | Expand all | Expand 10 after
5133 check->value()->BindTo(phi->InputAt(non_smi_input)->definition()); 5133 check->value()->BindTo(phi->InputAt(non_smi_input)->definition());
5134 5134
5135 phi->UpdateType(CompileType::FromCid(kSmiCid)); 5135 phi->UpdateType(CompileType::FromCid(kSmiCid));
5136 } 5136 }
5137 5137
5138 5138
5139 // Load instructions handled by load elimination. 5139 // Load instructions handled by load elimination.
5140 static bool IsLoadEliminationCandidate(Instruction* instr) { 5140 static bool IsLoadEliminationCandidate(Instruction* instr) {
5141 return instr->IsLoadField() 5141 return instr->IsLoadField()
5142 || instr->IsLoadIndexed() 5142 || instr->IsLoadIndexed()
5143 || instr->IsLoadStaticField() 5143 || instr->IsLoadStaticField();
5144 || instr->IsCurrentContext();
5145 } 5144 }
5146 5145
5147 5146
5148 static bool IsLoopInvariantLoad(ZoneGrowableArray<BitVector*>* sets, 5147 static bool IsLoopInvariantLoad(ZoneGrowableArray<BitVector*>* sets,
5149 intptr_t loop_header_index, 5148 intptr_t loop_header_index,
5150 Instruction* instr) { 5149 Instruction* instr) {
5151 return IsLoadEliminationCandidate(instr) && 5150 return IsLoadEliminationCandidate(instr) &&
5152 (sets != NULL) && 5151 (sets != NULL) &&
5153 instr->HasPlaceId() && 5152 instr->HasPlaceId() &&
5154 ((*sets)[loop_header_index] != NULL) && 5153 ((*sets)[loop_header_index] != NULL) &&
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
5277 5276
5278 // VMField location. Represented as a pair of an instance (SSA definition) 5277 // VMField location. Represented as a pair of an instance (SSA definition)
5279 // being accessed and offset to the field. 5278 // being accessed and offset to the field.
5280 kVMField, 5279 kVMField,
5281 5280
5282 // Indexed location with a non-constant index. 5281 // Indexed location with a non-constant index.
5283 kIndexed, 5282 kIndexed,
5284 5283
5285 // Indexed location with a constant index. 5284 // Indexed location with a constant index.
5286 kConstantIndexed, 5285 kConstantIndexed,
5287
5288 // Current context.
5289 kContext
5290 }; 5286 };
5291 5287
5292 Place(const Place& other) 5288 Place(const Place& other)
5293 : ValueObject(), 5289 : ValueObject(),
5294 kind_(other.kind_), 5290 kind_(other.kind_),
5295 representation_(other.representation_), 5291 representation_(other.representation_),
5296 instance_(other.instance_), 5292 instance_(other.instance_),
5297 raw_selector_(other.raw_selector_), 5293 raw_selector_(other.raw_selector_),
5298 id_(other.id_) { 5294 id_(other.id_) {
5299 } 5295 }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
5366 case Instruction::kStoreIndexed: { 5362 case Instruction::kStoreIndexed: {
5367 StoreIndexedInstr* store_indexed = instr->AsStoreIndexed(); 5363 StoreIndexedInstr* store_indexed = instr->AsStoreIndexed();
5368 representation_ = store_indexed-> 5364 representation_ = store_indexed->
5369 RequiredInputRepresentation(StoreIndexedInstr::kValuePos); 5365 RequiredInputRepresentation(StoreIndexedInstr::kValuePos);
5370 instance_ = store_indexed->array()->definition()->OriginalDefinition(); 5366 instance_ = store_indexed->array()->definition()->OriginalDefinition();
5371 SetIndex(store_indexed->index()->definition()); 5367 SetIndex(store_indexed->index()->definition());
5372 *is_store = true; 5368 *is_store = true;
5373 break; 5369 break;
5374 } 5370 }
5375 5371
5376 case Instruction::kCurrentContext:
5377 kind_ = kContext;
5378 ASSERT(instr->AsCurrentContext()->representation() == kTagged);
5379 representation_ = kTagged;
5380 *is_load = true;
5381 break;
5382
5383 case Instruction::kStoreContext:
5384 kind_ = kContext;
5385 ASSERT(instr->AsStoreContext()->RequiredInputRepresentation(
5386 StoreContextInstr::kValuePos) == kTagged);
5387 representation_ = kTagged;
5388 *is_store = true;
5389 break;
5390
5391 default: 5372 default:
5392 break; 5373 break;
5393 } 5374 }
5394 } 5375 }
5395 5376
5396 // Create object representing *[*] alias. 5377 // Create object representing *[*] alias.
5397 static Place* CreateAnyInstanceAnyIndexAlias(Isolate* isolate, 5378 static Place* CreateAnyInstanceAnyIndexAlias(Isolate* isolate,
5398 intptr_t id) { 5379 intptr_t id) {
5399 return Wrap(isolate, Place(kIndexed, NULL, 0), id); 5380 return Wrap(isolate, Place(kIndexed, NULL, 0), id);
5400 } 5381 }
(...skipping 19 matching lines...) Expand all
5420 } 5401 }
5421 5402
5422 bool DependsOnInstance() const { 5403 bool DependsOnInstance() const {
5423 switch (kind()) { 5404 switch (kind()) {
5424 case kField: 5405 case kField:
5425 case kVMField: 5406 case kVMField:
5426 case kIndexed: 5407 case kIndexed:
5427 case kConstantIndexed: 5408 case kConstantIndexed:
5428 return true; 5409 return true;
5429 5410
5430 case kContext:
5431 case kNone: 5411 case kNone:
5432 return false; 5412 return false;
5433 } 5413 }
5434 5414
5435 UNREACHABLE(); 5415 UNREACHABLE();
5436 return false; 5416 return false;
5437 } 5417 }
5438 5418
5439 // Given instance dependent alias X.f, X.@offs, X[C], X[*] return 5419 // Given instance dependent alias X.f, X.@offs, X[C], X[*] return
5440 // wild-card dependent alias *.f, *.@offs, *[C] or *[*] respectively. 5420 // wild-card dependent alias *.f, *.@offs, *[C] or *[*] respectively.
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
5520 return Isolate::Current()->current_zone()->PrintToString( 5500 return Isolate::Current()->current_zone()->PrintToString(
5521 "<%s[%s]>", 5501 "<%s[%s]>",
5522 DefinitionName(instance()), 5502 DefinitionName(instance()),
5523 DefinitionName(index())); 5503 DefinitionName(index()));
5524 5504
5525 case kConstantIndexed: 5505 case kConstantIndexed:
5526 return Isolate::Current()->current_zone()->PrintToString( 5506 return Isolate::Current()->current_zone()->PrintToString(
5527 "<%s[%" Pd "]>", 5507 "<%s[%" Pd "]>",
5528 DefinitionName(instance()), 5508 DefinitionName(instance()),
5529 index_constant()); 5509 index_constant());
5530
5531 case kContext:
5532 return "<context>";
5533 } 5510 }
5534 UNREACHABLE(); 5511 UNREACHABLE();
5535 return "<?>"; 5512 return "<?>";
5536 } 5513 }
5537 5514
5538 bool IsFinalField() const { 5515 bool IsFinalField() const {
5539 return (kind() == kField) && field().is_final(); 5516 return (kind() == kField) && field().is_final();
5540 } 5517 }
5541 5518
5542 intptr_t Hashcode() const { 5519 intptr_t Hashcode() const {
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
5949 } 5926 }
5950 } 5927 }
5951 break; 5928 break;
5952 5929
5953 case Place::kField: 5930 case Place::kField:
5954 case Place::kVMField: 5931 case Place::kVMField:
5955 if (CanBeAliased(alias->instance())) { 5932 if (CanBeAliased(alias->instance())) {
5956 // X.f or X.@offs alias with *.f and *.@offs respectively. 5933 // X.f or X.@offs alias with *.f and *.@offs respectively.
5957 CrossAlias(alias, alias->CopyWithoutInstance()); 5934 CrossAlias(alias, alias->CopyWithoutInstance());
5958 } 5935 }
5959 5936 break;
5960 case Place::kContext:
5961 return;
5962 5937
5963 case Place::kNone: 5938 case Place::kNone:
5964 UNREACHABLE(); 5939 UNREACHABLE();
5965 } 5940 }
5966 } 5941 }
5967 5942
5968 // Returns true if the given load is unaffected by external side-effects. 5943 // Returns true if the given load is unaffected by external side-effects.
5969 // This essentially means that no stores to the same location can 5944 // This essentially means that no stores to the same location can
5970 // occur in other functions. 5945 // occur in other functions.
5971 bool IsIndependentFromEffects(Place* place) { 5946 bool IsIndependentFromEffects(Place* place) {
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
6151 StoreInstanceFieldInstr* store_instance_field = instr->AsStoreInstanceField(); 6126 StoreInstanceFieldInstr* store_instance_field = instr->AsStoreInstanceField();
6152 if (store_instance_field != NULL) { 6127 if (store_instance_field != NULL) {
6153 return store_instance_field->value()->definition(); 6128 return store_instance_field->value()->definition();
6154 } 6129 }
6155 6130
6156 StoreStaticFieldInstr* store_static_field = instr->AsStoreStaticField(); 6131 StoreStaticFieldInstr* store_static_field = instr->AsStoreStaticField();
6157 if (store_static_field != NULL) { 6132 if (store_static_field != NULL) {
6158 return store_static_field->value()->definition(); 6133 return store_static_field->value()->definition();
6159 } 6134 }
6160 6135
6161 if (instr->IsStoreContext()) {
6162 return instr->InputAt(0)->definition();
6163 }
6164
6165 UNREACHABLE(); // Should only be called for supported store instructions. 6136 UNREACHABLE(); // Should only be called for supported store instructions.
6166 return NULL; 6137 return NULL;
6167 } 6138 }
6168 6139
6169 6140
6170 static bool IsPhiDependentPlace(Place* place) { 6141 static bool IsPhiDependentPlace(Place* place) {
6171 return ((place->kind() == Place::kField) || 6142 return ((place->kind() == Place::kField) ||
6172 (place->kind() == Place::kVMField)) && 6143 (place->kind() == Place::kVMField)) &&
6173 (place->instance() != NULL) && 6144 (place->instance() != NULL) &&
6174 place->instance()->IsPhi(); 6145 place->instance()->IsPhi();
(...skipping 1043 matching lines...) Expand 10 before | Expand all | Expand 10 after
7218 } 7189 }
7219 } 7190 }
7220 7191
7221 bool CanEliminateStore(Instruction* instr) { 7192 bool CanEliminateStore(Instruction* instr) {
7222 switch (instr->tag()) { 7193 switch (instr->tag()) {
7223 case Instruction::kStoreInstanceField: 7194 case Instruction::kStoreInstanceField:
7224 if (instr->AsStoreInstanceField()->is_initialization()) { 7195 if (instr->AsStoreInstanceField()->is_initialization()) {
7225 // Can't eliminate stores that initialized unboxed fields. 7196 // Can't eliminate stores that initialized unboxed fields.
7226 return false; 7197 return false;
7227 } 7198 }
7228 case Instruction::kStoreContext:
7229 case Instruction::kStoreIndexed: 7199 case Instruction::kStoreIndexed:
7230 case Instruction::kStoreStaticField: 7200 case Instruction::kStoreStaticField:
7231 return true; 7201 return true;
7232 default: 7202 default:
7233 UNREACHABLE(); 7203 UNREACHABLE();
7234 return false; 7204 return false;
7235 } 7205 }
7236 } 7206 }
7237 7207
7238 virtual void ComputeInitialSets() { 7208 virtual void ComputeInitialSets() {
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after
7758 SetReachable(instr->false_successor()); 7728 SetReachable(instr->false_successor());
7759 } 7729 }
7760 } 7730 }
7761 } 7731 }
7762 } 7732 }
7763 7733
7764 7734
7765 // -------------------------------------------------------------------------- 7735 // --------------------------------------------------------------------------
7766 // Analysis of non-definition instructions. They do not have values so they 7736 // Analysis of non-definition instructions. They do not have values so they
7767 // cannot have constant values. 7737 // cannot have constant values.
7768 void ConstantPropagator::VisitStoreContext(StoreContextInstr* instr) { }
7769
7770
7771 void ConstantPropagator::VisitCheckStackOverflow( 7738 void ConstantPropagator::VisitCheckStackOverflow(
7772 CheckStackOverflowInstr* instr) { } 7739 CheckStackOverflowInstr* instr) { }
7773 7740
7774 7741
7775 void ConstantPropagator::VisitCheckClass(CheckClassInstr* instr) { } 7742 void ConstantPropagator::VisitCheckClass(CheckClassInstr* instr) { }
7776 7743
7777 7744
7778 void ConstantPropagator::VisitCheckClassId(CheckClassIdInstr* instr) { } 7745 void ConstantPropagator::VisitCheckClassId(CheckClassIdInstr* instr) { }
7779 7746
7780 7747
(...skipping 2341 matching lines...) Expand 10 before | Expand all | Expand 10 after
10122 10089
10123 // Insert materializations at environment uses. 10090 // Insert materializations at environment uses.
10124 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { 10091 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) {
10125 CreateMaterializationAt( 10092 CreateMaterializationAt(
10126 exits_collector_.exits()[i], alloc, alloc->cls(), *slots); 10093 exits_collector_.exits()[i], alloc, alloc->cls(), *slots);
10127 } 10094 }
10128 } 10095 }
10129 10096
10130 10097
10131 } // namespace dart 10098 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698