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

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

Issue 207063002: Refactor to support multiple outputs in location summary (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 9 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 | « no previous file | runtime/vm/flow_graph_compiler.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_allocator.h" 5 #include "vm/flow_graph_allocator.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 #include "vm/il_printer.h" 9 #include "vm/il_printer.h"
10 #include "vm/flow_graph.h" 10 #include "vm/flow_graph.h"
(...skipping 840 matching lines...) Expand 10 before | Expand all | Expand 10 after
851 BitVector* interference_set) { 851 BitVector* interference_set) {
852 LocationSummary* locs = current->locs(); 852 LocationSummary* locs = current->locs();
853 853
854 Definition* def = current->AsDefinition(); 854 Definition* def = current->AsDefinition();
855 if ((def != NULL) && (def->AsConstant() != NULL)) { 855 if ((def != NULL) && (def->AsConstant() != NULL)) {
856 LiveRange* range = (def->ssa_temp_index() != -1) ? 856 LiveRange* range = (def->ssa_temp_index() != -1) ?
857 GetLiveRange(def->ssa_temp_index()) : NULL; 857 GetLiveRange(def->ssa_temp_index()) : NULL;
858 858
859 // Drop definitions of constants that have no uses. 859 // Drop definitions of constants that have no uses.
860 if ((range == NULL) || (range->first_use() == NULL)) { 860 if ((range == NULL) || (range->first_use() == NULL)) {
861 locs->set_out(Location::NoLocation()); 861 locs->set_out(0, Location::NoLocation());
862 return; 862 return;
863 } 863 }
864 864
865 // If this constant has only unconstrained uses convert them all 865 // If this constant has only unconstrained uses convert them all
866 // to use the constant directly and drop this definition. 866 // to use the constant directly and drop this definition.
867 // TODO(vegorov): improve allocation when we have enough registers to keep 867 // TODO(vegorov): improve allocation when we have enough registers to keep
868 // constants used in the loop in them. 868 // constants used in the loop in them.
869 if (HasOnlyUnconstrainedUses(range)) { 869 if (HasOnlyUnconstrainedUses(range)) {
870 const Object& value = def->AsConstant()->value(); 870 const Object& value = def->AsConstant()->value();
871 range->set_assigned_location(Location::Constant(value)); 871 range->set_assigned_location(Location::Constant(value));
872 range->set_spill_slot(Location::Constant(value)); 872 range->set_spill_slot(Location::Constant(value));
873 range->finger()->Initialize(range); 873 range->finger()->Initialize(range);
874 ConvertAllUses(range); 874 ConvertAllUses(range);
875 875
876 locs->set_out(Location::NoLocation()); 876 locs->set_out(0, Location::NoLocation());
877 return; 877 return;
878 } 878 }
879 } 879 }
880 880
881 const intptr_t pos = current->lifetime_position(); 881 const intptr_t pos = current->lifetime_position();
882 ASSERT(IsInstructionStartPosition(pos)); 882 ASSERT(IsInstructionStartPosition(pos));
883 883
884 // Number of input locations and number of input operands have to agree. 884 // Number of input locations and number of input operands have to agree.
885 ASSERT(locs->input_count() == current->InputCount()); 885 ASSERT(locs->input_count() == current->InputCount());
886 886
887 // Normalize same-as-first-input output if input is specified as 887 // Normalize same-as-first-input output if input is specified as
888 // fixed register. 888 // fixed register.
889 if (locs->out().IsUnallocated() && 889 if (locs->out(0).IsUnallocated() &&
890 (locs->out().policy() == Location::kSameAsFirstInput) && 890 (locs->out(0).policy() == Location::kSameAsFirstInput) &&
891 (locs->in(0).IsMachineRegister())) { 891 (locs->in(0).IsMachineRegister())) {
892 locs->set_out(locs->in(0)); 892 locs->set_out(0, locs->in(0));
893 } 893 }
894 894
895 const bool output_same_as_first_input = 895 const bool output_same_as_first_input =
896 locs->out().IsUnallocated() && 896 locs->out(0).IsUnallocated() &&
897 (locs->out().policy() == Location::kSameAsFirstInput); 897 (locs->out(0).policy() == Location::kSameAsFirstInput);
898 898
899 // Add uses from the deoptimization environment. 899 // Add uses from the deoptimization environment.
900 if (current->env() != NULL) ProcessEnvironmentUses(block, current); 900 if (current->env() != NULL) ProcessEnvironmentUses(block, current);
901 901
902 // Process inputs. 902 // Process inputs.
903 // Skip the first input if output is specified with kSameAsFirstInput policy, 903 // Skip the first input if output is specified with kSameAsFirstInput policy,
904 // they will be processed together at the very end. 904 // they will be processed together at the very end.
905 for (intptr_t j = output_same_as_first_input ? 1 : 0; 905 for (intptr_t j = output_same_as_first_input ? 1 : 0;
906 j < current->InputCount(); 906 j < current->InputCount();
907 j++) { 907 j++) {
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1010 // locations. Every register is blocked now so attempt to 1010 // locations. Every register is blocked now so attempt to
1011 // allocate will not succeed. 1011 // allocate will not succeed.
1012 for (intptr_t j = 0; j < locs->temp_count(); j++) { 1012 for (intptr_t j = 0; j < locs->temp_count(); j++) {
1013 ASSERT(!locs->temp(j).IsUnallocated()); 1013 ASSERT(!locs->temp(j).IsUnallocated());
1014 } 1014 }
1015 1015
1016 for (intptr_t j = 0; j < locs->input_count(); j++) { 1016 for (intptr_t j = 0; j < locs->input_count(); j++) {
1017 ASSERT(!locs->in(j).IsUnallocated()); 1017 ASSERT(!locs->in(j).IsUnallocated());
1018 } 1018 }
1019 1019
1020 ASSERT(!locs->out().IsUnallocated()); 1020 ASSERT(!locs->out(0).IsUnallocated());
1021 #endif 1021 #endif
1022 } 1022 }
1023 1023
1024 if (locs->can_call()) { 1024 if (locs->can_call()) {
1025 safepoints_.Add(current); 1025 safepoints_.Add(current);
1026 } 1026 }
1027 1027
1028 if (def == NULL) { 1028 if (def == NULL) {
1029 ASSERT(locs->out().IsInvalid()); 1029 ASSERT(locs->out(0).IsInvalid());
1030 return; 1030 return;
1031 } 1031 }
1032 1032
1033 if (locs->out().IsInvalid()) { 1033 if (locs->out(0).IsInvalid()) {
1034 ASSERT(def->ssa_temp_index() < 0); 1034 ASSERT(def->ssa_temp_index() < 0);
1035 return; 1035 return;
1036 } 1036 }
1037 1037
1038 // We might have a definition without use. We do not assign SSA index to 1038 // We might have a definition without use. We do not assign SSA index to
1039 // such definitions. 1039 // such definitions.
1040 LiveRange* range = (def->ssa_temp_index() >= 0) ? 1040 LiveRange* range = (def->ssa_temp_index() >= 0) ?
1041 GetLiveRange(def->ssa_temp_index()) : 1041 GetLiveRange(def->ssa_temp_index()) :
1042 MakeLiveRangeForTemporary(); 1042 MakeLiveRangeForTemporary();
1043 Location* out = locs->out_slot(); 1043 Location* out = locs->out_slot(0);
1044 1044
1045 // Process output and finalize its liverange. 1045 // Process output and finalize its liverange.
1046 if (out->IsMachineRegister()) { 1046 if (out->IsMachineRegister()) {
1047 // Fixed output location. Expected shape of live range: 1047 // Fixed output location. Expected shape of live range:
1048 // 1048 //
1049 // i i' j j' 1049 // i i' j j'
1050 // register [--) 1050 // register [--)
1051 // output [------- 1051 // output [-------
1052 // 1052 //
1053 BlockLocation(*out, pos, pos + 1); 1053 BlockLocation(*out, pos, pos + 1);
(...skipping 29 matching lines...) Expand all
1083 // start. Expected shape of live ranges: 1083 // start. Expected shape of live ranges:
1084 // 1084 //
1085 // i i' 1085 // i i'
1086 // input #0 --* 1086 // input #0 --*
1087 // output [---- 1087 // output [----
1088 // 1088 //
1089 ASSERT(locs->in(0).Equals(Location::RequiresRegister()) || 1089 ASSERT(locs->in(0).Equals(Location::RequiresRegister()) ||
1090 locs->in(0).Equals(Location::RequiresFpuRegister())); 1090 locs->in(0).Equals(Location::RequiresFpuRegister()));
1091 1091
1092 // Create move that will copy value between input and output. 1092 // Create move that will copy value between input and output.
1093 locs->set_out(Location::RequiresRegister()); 1093 locs->set_out(0, Location::RequiresRegister());
1094 MoveOperands* move = AddMoveAt(pos, 1094 MoveOperands* move = AddMoveAt(pos,
1095 Location::RequiresRegister(), 1095 Location::RequiresRegister(),
1096 Location::Any()); 1096 Location::Any());
1097 1097
1098 // Add uses to the live range of the input. 1098 // Add uses to the live range of the input.
1099 Definition* input = current->InputAt(0)->definition(); 1099 Definition* input = current->InputAt(0)->definition();
1100 LiveRange* input_range = 1100 LiveRange* input_range =
1101 GetLiveRange(input->ssa_temp_index()); 1101 GetLiveRange(input->ssa_temp_index());
1102 input_range->AddUseInterval(block->start_pos(), pos); 1102 input_range->AddUseInterval(block->start_pos(), pos);
1103 input_range->AddUse(pos, move->src_slot()); 1103 input_range->AddUse(pos, move->src_slot());
(...skipping 10 matching lines...) Expand all
1114 interference_set->Contains(range->vreg())) { 1114 interference_set->Contains(range->vreg())) {
1115 interference_set->Add(input->ssa_temp_index()); 1115 interference_set->Add(input->ssa_temp_index());
1116 } 1116 }
1117 } else { 1117 } else {
1118 // Normal unallocated location that requires a register. Expected shape of 1118 // Normal unallocated location that requires a register. Expected shape of
1119 // live range: 1119 // live range:
1120 // 1120 //
1121 // i i' 1121 // i i'
1122 // output [------- 1122 // output [-------
1123 // 1123 //
1124 ASSERT(locs->out().Equals(Location::RequiresRegister()) || 1124 ASSERT(locs->out(0).Equals(Location::RequiresRegister()) ||
1125 locs->out().Equals(Location::RequiresFpuRegister())); 1125 locs->out(0).Equals(Location::RequiresFpuRegister()));
1126 1126
1127 // Shorten live range to the point of definition and add use to be filled by 1127 // Shorten live range to the point of definition and add use to be filled by
1128 // allocator. 1128 // allocator.
1129 range->DefineAt(pos); 1129 range->DefineAt(pos);
1130 range->AddUse(pos, out); 1130 range->AddUse(pos, out);
1131 } 1131 }
1132 1132
1133 AssignSafepoints(range); 1133 AssignSafepoints(range);
1134 CompleteRange(range, RegisterKindForResult(current)); 1134 CompleteRange(range, RegisterKindForResult(current));
1135 } 1135 }
(...skipping 1469 matching lines...) Expand 10 before | Expand all | Expand 10 after
2605 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", 2605 OS::Print("-- [after ssa allocator] ir [%s] -------------\n",
2606 function.ToFullyQualifiedCString()); 2606 function.ToFullyQualifiedCString());
2607 FlowGraphPrinter printer(flow_graph_, true); 2607 FlowGraphPrinter printer(flow_graph_, true);
2608 printer.PrintBlocks(); 2608 printer.PrintBlocks();
2609 OS::Print("----------------------------------------------\n"); 2609 OS::Print("----------------------------------------------\n");
2610 } 2610 }
2611 } 2611 }
2612 2612
2613 2613
2614 } // namespace dart 2614 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/flow_graph_compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698