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

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

Issue 14846022: Use the constant pool for all constants, not just null. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 7 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/flow_graph.h ('k') | runtime/vm/flow_graph_inliner.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) 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/flow_graph.h" 5 #include "vm/flow_graph.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/flow_graph_builder.h" 8 #include "vm/flow_graph_builder.h"
9 #include "vm/intermediate_language.h" 9 #include "vm/intermediate_language.h"
10 #include "vm/longjump.h" 10 #include "vm/longjump.h"
(...skipping 16 matching lines...) Expand all
27 num_stack_locals_(builder.num_stack_locals()), 27 num_stack_locals_(builder.num_stack_locals()),
28 graph_entry_(graph_entry), 28 graph_entry_(graph_entry),
29 preorder_(), 29 preorder_(),
30 postorder_(), 30 postorder_(),
31 reverse_postorder_(), 31 reverse_postorder_(),
32 block_effects_(NULL) { 32 block_effects_(NULL) {
33 DiscoverBlocks(); 33 DiscoverBlocks();
34 } 34 }
35 35
36 36
37 ConstantInstr* FlowGraph::AddConstantToInitialDefinitions( 37 ConstantInstr* FlowGraph::GetConstant(const Object& object) {
38 const Object& object) {
39 // Check if the constant is already in the pool. 38 // Check if the constant is already in the pool.
40 for (intptr_t i = 0; i < graph_entry_->initial_definitions()->length(); ++i) { 39 GrowableArray<Definition*>* pool = graph_entry_->initial_definitions();
41 ConstantInstr* constant = 40 for (intptr_t i = 0; i < pool->length(); ++i) {
42 (*graph_entry_->initial_definitions())[i]->AsConstant(); 41 ConstantInstr* constant = (*pool)[i]->AsConstant();
43 if ((constant != NULL) && (constant->value().raw() == object.raw())) { 42 if ((constant != NULL) && (constant->value().raw() == object.raw())) {
44 return constant; 43 return constant;
45 } 44 }
46 } 45 }
47 // Otherwise, allocate and add it to the pool. 46 // Otherwise, allocate and add it to the pool.
48 ConstantInstr* constant = new ConstantInstr(object); 47 ConstantInstr* constant = new ConstantInstr(object);
49 constant->set_ssa_temp_index(alloc_ssa_temp_index()); 48 constant->set_ssa_temp_index(alloc_ssa_temp_index());
50 AddToInitialDefinitions(constant); 49 AddToInitialDefinitions(constant);
51 return constant; 50 return constant;
52 } 51 }
53 52
53
54 void FlowGraph::AddToInitialDefinitions(Definition* defn) { 54 void FlowGraph::AddToInitialDefinitions(Definition* defn) {
55 // TODO(zerny): Set previous to the graph entry so it is accessible by 55 // TODO(zerny): Set previous to the graph entry so it is accessible by
56 // GetBlock. Remove this once there is a direct pointer to the block. 56 // GetBlock. Remove this once there is a direct pointer to the block.
57 defn->set_previous(graph_entry_); 57 defn->set_previous(graph_entry_);
58 graph_entry_->initial_definitions()->Add(defn); 58 graph_entry_->initial_definitions()->Add(defn);
59 } 59 }
60 60
61 61
62 void FlowGraph::InsertBefore(Instruction* next, 62 void FlowGraph::InsertBefore(Instruction* next,
63 Instruction* instr, 63 Instruction* instr,
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 ZoneGrowableArray<Definition*>* inlining_parameters) { 618 ZoneGrowableArray<Definition*>* inlining_parameters) {
619 // TODO(fschneider): Support catch-entry. 619 // TODO(fschneider): Support catch-entry.
620 if (graph_entry_->SuccessorCount() > 1) { 620 if (graph_entry_->SuccessorCount() > 1) {
621 Bailout("Catch-entry support in SSA."); 621 Bailout("Catch-entry support in SSA.");
622 } 622 }
623 623
624 // Initial renaming environment. 624 // Initial renaming environment.
625 GrowableArray<Definition*> env(variable_count()); 625 GrowableArray<Definition*> env(variable_count());
626 626
627 // Add global constants to the initial definitions. 627 // Add global constants to the initial definitions.
628 constant_null_ = 628 constant_null_ = GetConstant(Object::ZoneHandle());
629 AddConstantToInitialDefinitions(Object::ZoneHandle());
630 629
631 // Add parameters to the initial definitions and renaming environment. 630 // Add parameters to the initial definitions and renaming environment.
632 if (inlining_parameters != NULL) { 631 if (inlining_parameters != NULL) {
633 // Use known parameters. 632 // Use known parameters.
634 ASSERT(parameter_count() == inlining_parameters->length()); 633 ASSERT(parameter_count() == inlining_parameters->length());
635 for (intptr_t i = 0; i < parameter_count(); ++i) { 634 for (intptr_t i = 0; i < parameter_count(); ++i) {
636 Definition* defn = (*inlining_parameters)[i]; 635 Definition* defn = (*inlining_parameters)[i];
637 defn->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. 636 defn->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp.
638 AddToInitialDefinitions(defn); 637 AddToInitialDefinitions(defn);
639 env.Add(defn); 638 env.Add(defn);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
691 phi->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. 690 phi->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp.
692 } 691 }
693 } 692 }
694 } 693 }
695 } 694 }
696 695
697 // Attach environment to the block entry. 696 // Attach environment to the block entry.
698 AttachEnvironment(block_entry, env); 697 AttachEnvironment(block_entry, env);
699 698
700 // 2. Process normal instructions. 699 // 2. Process normal instructions.
701
702 for (ForwardInstructionIterator it(block_entry); !it.Done(); it.Advance()) { 700 for (ForwardInstructionIterator it(block_entry); !it.Done(); it.Advance()) {
703 Instruction* current = it.Current(); 701 Instruction* current = it.Current();
704 702
705 // Attach current environment to the instructions that need it. 703 // Attach current environment to the instructions that need it.
706 if (current->NeedsEnvironment()) { 704 if (current->NeedsEnvironment()) {
707 AttachEnvironment(current, env); 705 AttachEnvironment(current, env);
708 } 706 }
709 707
710 // 2a. Handle uses: 708 // 2a. Handle uses:
711 // Update expression stack environment for each use. 709 // Update the expression stack renaming environment for each use by
712 // For each use of a LoadLocal or StoreLocal: Replace it with the value 710 // removing the renamed value.
713 // from the environment. 711 // For each use of a LoadLocal, StoreLocal, or Constant: Replace it with
712 // the renamed value.
714 for (intptr_t i = current->InputCount() - 1; i >= 0; --i) { 713 for (intptr_t i = current->InputCount() - 1; i >= 0; --i) {
715 Value* v = current->InputAt(i); 714 Value* v = current->InputAt(i);
716 // Update expression stack. 715 // Update expression stack.
717 ASSERT(env->length() > variable_count()); 716 ASSERT(env->length() > variable_count());
718 717
719 Definition* reaching_defn = env->RemoveLast(); 718 Definition* reaching_defn = env->RemoveLast();
720
721 Definition* input_defn = v->definition(); 719 Definition* input_defn = v->definition();
722 if (input_defn->IsLoadLocal() || input_defn->IsStoreLocal()) { 720 if (input_defn->IsLoadLocal() ||
721 input_defn->IsStoreLocal() ||
722 input_defn->IsConstant()) {
723 // Remove the load/store from the graph. 723 // Remove the load/store from the graph.
724 input_defn->RemoveFromGraph(); 724 input_defn->RemoveFromGraph();
725 // Assert we are not referencing nulls in the initial environment. 725 // Assert we are not referencing nulls in the initial environment.
726 ASSERT(reaching_defn->ssa_temp_index() != -1); 726 ASSERT(reaching_defn->ssa_temp_index() != -1);
727 v->set_definition(reaching_defn); 727 v->set_definition(reaching_defn);
728 input_defn = reaching_defn; 728 input_defn = reaching_defn;
729 } 729 }
730 input_defn->AddInputUse(v); 730 input_defn->AddInputUse(v);
731 } 731 }
732 732
733 // Drop pushed arguments for calls. 733 // Drop pushed arguments for calls.
734 for (intptr_t j = 0; j < current->ArgumentCount(); j++) { 734 for (intptr_t j = 0; j < current->ArgumentCount(); j++) {
735 env->RemoveLast(); 735 env->RemoveLast();
736 } 736 }
737 737
738 // 2b. Handle LoadLocal and StoreLocal. 738 // 2b. Handle LoadLocal, StoreLocal, and Constant.
739 // For each LoadLocal: Remove it from the graph.
740 // For each StoreLocal: Remove it from the graph and update the environment.
741 Definition* definition = current->AsDefinition(); 739 Definition* definition = current->AsDefinition();
742 if (definition != NULL) { 740 if (definition != NULL) {
743 LoadLocalInstr* load = definition->AsLoadLocal(); 741 LoadLocalInstr* load = definition->AsLoadLocal();
744 StoreLocalInstr* store = definition->AsStoreLocal(); 742 StoreLocalInstr* store = definition->AsStoreLocal();
745 if ((load != NULL) || (store != NULL)) { 743 ConstantInstr* constant = definition->AsConstant();
744 if ((load != NULL) || (store != NULL) || (constant != NULL)) {
746 intptr_t index; 745 intptr_t index;
747 Definition* result; 746 Definition* result;
748 if (store != NULL) { 747 if (store != NULL) {
749 // Update renaming environment. 748 // Update renaming environment.
750 index = store->local().BitIndexIn(num_non_copied_params_); 749 index = store->local().BitIndexIn(num_non_copied_params_);
751 result = store->value()->definition(); 750 result = store->value()->definition();
752 751
753 if (variable_liveness->IsStoreAlive(block_entry, store)) { 752 if (variable_liveness->IsStoreAlive(block_entry, store)) {
754 (*env)[index] = result; 753 (*env)[index] = result;
755 } else { 754 } else {
756 (*env)[index] = constant_null(); 755 (*env)[index] = constant_null();
757 } 756 }
758 } else { 757 } else if (load != NULL) {
759 // The graph construction ensures we do not have an unused LoadLocal 758 // The graph construction ensures we do not have an unused LoadLocal
760 // computation. 759 // computation.
761 ASSERT(definition->is_used()); 760 ASSERT(definition->is_used());
762 index = load->local().BitIndexIn(num_non_copied_params_); 761 index = load->local().BitIndexIn(num_non_copied_params_);
763 result = (*env)[index]; 762 result = (*env)[index];
764 763
765 PhiInstr* phi = result->AsPhi(); 764 PhiInstr* phi = result->AsPhi();
766 if ((phi != NULL) && !phi->is_alive()) { 765 if ((phi != NULL) && !phi->is_alive()) {
767 phi->mark_alive(); 766 phi->mark_alive();
768 live_phis->Add(phi); 767 live_phis->Add(phi);
769 } 768 }
770 769
771 if (variable_liveness->IsLastLoad(block_entry, load)) { 770 if (variable_liveness->IsLastLoad(block_entry, load)) {
772 (*env)[index] = constant_null(); 771 (*env)[index] = constant_null();
773 } 772 }
773 } else {
774 ASSERT(definition->is_used());
775 result = GetConstant(constant->value());
774 } 776 }
775 // Update expression stack or remove from graph. 777 // Update expression stack or remove from graph.
776 if (definition->is_used()) { 778 if (definition->is_used()) {
779 ASSERT(result != NULL);
777 env->Add(result); 780 env->Add(result);
778 // We remove load/store instructions when we find their use in 2a. 781 // We remove load/store/constant instructions when we find their
782 // use in 2a.
779 } else { 783 } else {
780 it.RemoveCurrentFromGraph(); 784 it.RemoveCurrentFromGraph();
781 } 785 }
782 } else { 786 } else {
783 // Not a load or store. 787 // Not a load, store, or constant.
784 if (definition->is_used()) { 788 if (definition->is_used()) {
785 // Assign fresh SSA temporary and update expression stack. 789 // Assign fresh SSA temporary and update expression stack.
786 definition->set_ssa_temp_index(alloc_ssa_temp_index()); 790 definition->set_ssa_temp_index(alloc_ssa_temp_index());
787 env->Add(definition); 791 env->Add(definition);
788 } 792 }
789 } 793 }
790 } 794 }
791 795
792 // 2c. Handle pushed argument. 796 // 2c. Handle pushed argument.
793 PushArgumentInstr* push = current->AsPushArgument(); 797 PushArgumentInstr* push = current->AsPushArgument();
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
1052 } 1056 }
1053 1057
1054 1058
1055 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from, 1059 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from,
1056 BlockEntryInstr* to) const { 1060 BlockEntryInstr* to) const {
1057 return available_at_[to->postorder_number()]->Contains( 1061 return available_at_[to->postorder_number()]->Contains(
1058 from->postorder_number()); 1062 from->postorder_number());
1059 } 1063 }
1060 1064
1061 } // namespace dart 1065 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph.h ('k') | runtime/vm/flow_graph_inliner.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698