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

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

Issue 13801014: Fix bug in ParallelMoveResolver::EmitSwap: implement swaps of FPU spill slots. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix typo Created 7 years, 8 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
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/globals.h" // Needed here to get TARGET_ARCH_XXX. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_XXX.
6 6
7 #include "vm/flow_graph_compiler.h" 7 #include "vm/flow_graph_compiler.h"
8 8
9 #include "vm/cha.h" 9 #include "vm/cha.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 intptr_t slot_ix = 0; 72 intptr_t slot_ix = 0;
73 Environment* current = deoptimization_env_; 73 Environment* current = deoptimization_env_;
74 74
75 // For the innermost environment, call the virtual return builder. 75 // For the innermost environment, call the virtual return builder.
76 BuildReturnAddress(builder, current->function(), slot_ix++); 76 BuildReturnAddress(builder, current->function(), slot_ix++);
77 77
78 // For the innermost environment, set outgoing arguments and the locals. 78 // For the innermost environment, set outgoing arguments and the locals.
79 for (intptr_t i = current->Length() - 1; 79 for (intptr_t i = current->Length() - 1;
80 i >= current->fixed_parameter_count(); 80 i >= current->fixed_parameter_count();
81 i--) { 81 i--) {
82 builder->AddCopy(current->LocationAt(i), slot_ix++); 82 builder->AddCopy(current->ValueAt(i), current->LocationAt(i), slot_ix++);
83 } 83 }
84 84
85 // PC marker and caller FP. 85 // PC marker and caller FP.
86 builder->AddPcMarker(current->function(), slot_ix++); 86 builder->AddPcMarker(current->function(), slot_ix++);
87 builder->AddCallerFp(slot_ix++); 87 builder->AddCallerFp(slot_ix++);
88 88
89 Environment* previous = current; 89 Environment* previous = current;
90 current = current->outer(); 90 current = current->outer();
91 while (current != NULL) { 91 while (current != NULL) {
92 // For any outer environment the deopt id is that of the call instruction 92 // For any outer environment the deopt id is that of the call instruction
93 // which is recorded in the outer environment. 93 // which is recorded in the outer environment.
94 builder->AddReturnAddressAfter(current->function(), 94 builder->AddReturnAddressAfter(current->function(),
95 current->deopt_id(), 95 current->deopt_id(),
96 slot_ix++); 96 slot_ix++);
97 97
98 // The values of outgoing arguments can be changed from the inlined call so 98 // The values of outgoing arguments can be changed from the inlined call so
99 // we must read them from the previous environment. 99 // we must read them from the previous environment.
100 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) { 100 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) {
101 builder->AddCopy(previous->LocationAt(i), slot_ix++); 101 builder->AddCopy(previous->ValueAt(i),
102 previous->LocationAt(i),
103 slot_ix++);
102 } 104 }
103 105
104 // Set the locals, note that outgoing arguments are not in the environment. 106 // Set the locals, note that outgoing arguments are not in the environment.
105 for (intptr_t i = current->Length() - 1; 107 for (intptr_t i = current->Length() - 1;
106 i >= current->fixed_parameter_count(); 108 i >= current->fixed_parameter_count();
107 i--) { 109 i--) {
108 builder->AddCopy(current->LocationAt(i), slot_ix++); 110 builder->AddCopy(current->ValueAt(i),
111 current->LocationAt(i),
112 slot_ix++);
109 } 113 }
110 114
111 // PC marker and caller FP. 115 // PC marker and caller FP.
112 builder->AddPcMarker(current->function(), slot_ix++); 116 builder->AddPcMarker(current->function(), slot_ix++);
113 builder->AddCallerFp(slot_ix++); 117 builder->AddCallerFp(slot_ix++);
114 118
115 // Iterate on the outer environment. 119 // Iterate on the outer environment.
116 previous = current; 120 previous = current;
117 current = current->outer(); 121 current = current->outer();
118 } 122 }
119 // The previous pointer is now the outermost environment. 123 // The previous pointer is now the outermost environment.
120 ASSERT(previous != NULL); 124 ASSERT(previous != NULL);
121 125
122 // For the outermost environment, set caller PC. 126 // For the outermost environment, set caller PC.
123 builder->AddCallerPc(slot_ix++); 127 builder->AddCallerPc(slot_ix++);
124 128
125 // For the outermost environment, set the incoming arguments. 129 // For the outermost environment, set the incoming arguments.
126 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) { 130 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) {
127 builder->AddCopy(previous->LocationAt(i), slot_ix++); 131 builder->AddCopy(previous->ValueAt(i), previous->LocationAt(i), slot_ix++);
128 } 132 }
129 133
130 const DeoptInfo& deopt_info = DeoptInfo::Handle(builder->CreateDeoptInfo()); 134 const DeoptInfo& deopt_info = DeoptInfo::Handle(builder->CreateDeoptInfo());
131 return deopt_info.raw(); 135 return deopt_info.raw();
132 } 136 }
133 137
134 138
135 FlowGraphCompiler::FlowGraphCompiler(Assembler* assembler, 139 FlowGraphCompiler::FlowGraphCompiler(Assembler* assembler,
136 const FlowGraph& flow_graph, 140 const FlowGraph& flow_graph,
137 bool is_optimizing) 141 bool is_optimizing)
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 RegisterSet* regs = locs->live_registers(); 413 RegisterSet* regs = locs->live_registers();
410 if (regs->fpu_regs_count() > 0) { 414 if (regs->fpu_regs_count() > 0) {
411 // Denote FPU registers with 0 bits in the stackmap. Based on the 415 // Denote FPU registers with 0 bits in the stackmap. Based on the
412 // assumption that there are normally few live FPU registers, this 416 // assumption that there are normally few live FPU registers, this
413 // encoding is simpler and roughly as compact as storing a separate 417 // encoding is simpler and roughly as compact as storing a separate
414 // count of FPU registers. 418 // count of FPU registers.
415 // 419 //
416 // FPU registers have the highest register number at the highest 420 // FPU registers have the highest register number at the highest
417 // address (i.e., first in the stackmap). 421 // address (i.e., first in the stackmap).
418 const intptr_t kFpuRegisterSpillFactor = 422 const intptr_t kFpuRegisterSpillFactor =
419 FlowGraphAllocator::kFpuRegisterSpillFactor; 423 kFpuRegisterSize / kWordSize;
420 for (intptr_t i = kNumberOfFpuRegisters - 1; i >= 0; --i) { 424 for (intptr_t i = kNumberOfFpuRegisters - 1; i >= 0; --i) {
421 FpuRegister reg = static_cast<FpuRegister>(i); 425 FpuRegister reg = static_cast<FpuRegister>(i);
422 if (regs->ContainsFpuRegister(reg)) { 426 if (regs->ContainsFpuRegister(reg)) {
423 for (intptr_t j = 0; j < kFpuRegisterSpillFactor; ++j) { 427 for (intptr_t j = 0; j < kFpuRegisterSpillFactor; ++j) {
424 bitmap->Set(bitmap->Length(), false); 428 bitmap->Set(bitmap->Length(), false);
425 } 429 }
426 } 430 }
427 } 431 }
428 } 432 }
429 // General purpose registers have the lowest register number at the 433 // General purpose registers have the lowest register number at the
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after
937 EmitSwap(index); 941 EmitSwap(index);
938 return; 942 return;
939 } 943 }
940 } 944 }
941 945
942 // This move is not blocked. 946 // This move is not blocked.
943 EmitMove(index); 947 EmitMove(index);
944 } 948 }
945 949
946 950
951 bool ParallelMoveResolver::IsScratchLocation(Location loc) {
952 for (int i = 0; i < moves_.length(); ++i) {
953 if (moves_[i]->Blocks(loc)) {
954 return false;
955 }
956 }
957
958 for (int i = 0; i < moves_.length(); ++i) {
959 if (moves_[i]->dest().Equals(loc)) {
960 return true;
961 }
962 }
963
964 return false;
965 }
966
967
968 intptr_t ParallelMoveResolver::AllocateScratchRegister(Location::Kind kind,
969 intptr_t blocked,
970 intptr_t register_count,
971 bool* spilled) {
972 intptr_t scratch = -1;
973 for (intptr_t reg = 0; reg < register_count; reg++) {
974 if ((blocked != reg) &&
975 IsScratchLocation(Location::MachineRegisterLocation(kind, reg))) {
976 scratch = reg;
977 break;
978 }
979 }
980
981 if (scratch == -1) {
982 *spilled = true;
983 for (intptr_t reg = 0; reg < register_count; reg++) {
984 if (blocked != reg) {
985 scratch = reg;
986 }
987 }
988 } else {
989 *spilled = false;
990 }
991
992 return scratch;
993 }
994
995
996 ParallelMoveResolver::ScratchFpuRegisterScope::ScratchFpuRegisterScope(
997 ParallelMoveResolver* resolver, FpuRegister blocked)
998 : resolver_(resolver),
999 reg_(kNoFpuRegister),
1000 spilled_(false) {
1001 reg_ = static_cast<FpuRegister>(
1002 resolver_->AllocateScratchRegister(Location::kFpuRegister,
1003 blocked,
1004 kNumberOfFpuRegisters,
1005 &spilled_));
1006
1007 if (spilled_) {
1008 resolver->SpillFpuScratch(reg_);
1009 }
1010 }
1011
1012
1013 ParallelMoveResolver::ScratchFpuRegisterScope::~ScratchFpuRegisterScope() {
1014 if (spilled_) {
1015 resolver_->RestoreFpuScratch(reg_);
1016 }
1017 }
1018
1019
1020 ParallelMoveResolver::ScratchRegisterScope::ScratchRegisterScope(
1021 ParallelMoveResolver* resolver, Register blocked)
1022 : resolver_(resolver),
1023 reg_(kNoRegister),
1024 spilled_(false) {
1025 reg_ = static_cast<Register>(
1026 resolver_->AllocateScratchRegister(Location::kRegister,
1027 blocked,
1028 kNumberOfCpuRegisters,
1029 &spilled_));
1030
1031 if (spilled_) {
1032 resolver->SpillScratch(reg_);
1033 }
1034 }
1035
1036
1037 ParallelMoveResolver::ScratchRegisterScope::~ScratchRegisterScope() {
1038 if (spilled_) {
1039 resolver_->RestoreScratch(reg_);
1040 }
1041 }
1042
1043
947 intptr_t FlowGraphCompiler::ElementSizeFor(intptr_t cid) { 1044 intptr_t FlowGraphCompiler::ElementSizeFor(intptr_t cid) {
948 if (RawObject::IsExternalTypedDataClassId(cid)) { 1045 if (RawObject::IsExternalTypedDataClassId(cid)) {
949 return ExternalTypedData::ElementSizeInBytes(cid); 1046 return ExternalTypedData::ElementSizeInBytes(cid);
950 } else if (RawObject::IsTypedDataClassId(cid)) { 1047 } else if (RawObject::IsTypedDataClassId(cid)) {
951 return TypedData::ElementSizeInBytes(cid); 1048 return TypedData::ElementSizeInBytes(cid);
952 } 1049 }
953 switch (cid) { 1050 switch (cid) {
954 case kArrayCid: 1051 case kArrayCid:
955 case kImmutableArrayCid: 1052 case kImmutableArrayCid:
956 return Array::kBytesPerElement; 1053 return Array::kBytesPerElement;
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1037 if (i != largest_ix) { 1134 if (i != largest_ix) {
1038 // Swap. 1135 // Swap.
1039 CidTarget temp = (*sorted)[i]; 1136 CidTarget temp = (*sorted)[i];
1040 (*sorted)[i] = (*sorted)[largest_ix]; 1137 (*sorted)[i] = (*sorted)[largest_ix];
1041 (*sorted)[largest_ix] = temp; 1138 (*sorted)[largest_ix] = temp;
1042 } 1139 }
1043 } 1140 }
1044 } 1141 }
1045 1142
1046 } // namespace dart 1143 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698