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

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: Add comments 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 ParallelMoveResolver::ScratchFpuRegisterScope::ScratchFpuRegisterScope(
Florian Schneider 2013/04/09 09:44:27 Can you implement ScratchFpuRegisterScope in using
969 ParallelMoveResolver* resolver)
970 : resolver_(resolver),
971 reg_(kNoXmmRegister),
972 spilled_(false) {
973 ASSERT(XMM0 == 0);
974 for (intptr_t reg = 1; reg < kNumberOfFpuRegisters; reg++) {
975 Location scratch = Location::FpuRegisterLocation(
976 static_cast<FpuRegister>(reg));
977 if (resolver->IsScratchLocation(scratch)) {
978 reg_ = static_cast<FpuRegister>(reg);
979 break;
980 }
981 }
982
983 if (reg_ == kNoXmmRegister) {
984 spilled_ = true;
985 reg_ = XMM1;
986 resolver->SpillFpuScratch(reg_);
987 }
988 }
989
990
991 ParallelMoveResolver::ScratchFpuRegisterScope::~ScratchFpuRegisterScope() {
992 if (spilled_) {
993 resolver_->RestoreFpuScratch(reg_);
994 }
995 }
996
997
998 ParallelMoveResolver::ScratchRegisterScope::ScratchRegisterScope(
999 ParallelMoveResolver* resolver, Register blocked)
1000 : resolver_(resolver),
1001 reg_(kNoRegister),
1002 spilled_(false) {
1003 for (intptr_t reg = 0; reg < kNumberOfCpuRegisters; reg++) {
1004 if (blocked == reg) {
1005 continue;
1006 }
1007
1008 Location scratch = Location::RegisterLocation(
1009 static_cast<Register>(reg));
1010 if (resolver->IsScratchLocation(scratch)) {
1011 reg_ = static_cast<Register>(reg);
1012 break;
1013 }
1014 }
1015
1016 if (reg_ == kNoRegister) {
1017 spilled_ = true;
1018 for (intptr_t reg = 0; reg < kNumberOfCpuRegisters; reg++) {
1019 if (blocked != reg) {
1020 reg_ = static_cast<Register>(reg);
1021 break;
1022 }
1023 }
1024 resolver->SpillScratch(reg_);
1025 }
1026 }
1027
1028
1029 ParallelMoveResolver::ScratchRegisterScope::~ScratchRegisterScope() {
1030 if (spilled_) {
1031 resolver_->RestoreScratch(reg_);
1032 }
1033 }
1034
1035
947 intptr_t FlowGraphCompiler::ElementSizeFor(intptr_t cid) { 1036 intptr_t FlowGraphCompiler::ElementSizeFor(intptr_t cid) {
948 if (RawObject::IsExternalTypedDataClassId(cid)) { 1037 if (RawObject::IsExternalTypedDataClassId(cid)) {
949 return ExternalTypedData::ElementSizeInBytes(cid); 1038 return ExternalTypedData::ElementSizeInBytes(cid);
950 } else if (RawObject::IsTypedDataClassId(cid)) { 1039 } else if (RawObject::IsTypedDataClassId(cid)) {
951 return TypedData::ElementSizeInBytes(cid); 1040 return TypedData::ElementSizeInBytes(cid);
952 } 1041 }
953 switch (cid) { 1042 switch (cid) {
954 case kArrayCid: 1043 case kArrayCid:
955 case kImmutableArrayCid: 1044 case kImmutableArrayCid:
956 return Array::kBytesPerElement; 1045 return Array::kBytesPerElement;
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1037 if (i != largest_ix) { 1126 if (i != largest_ix) {
1038 // Swap. 1127 // Swap.
1039 CidTarget temp = (*sorted)[i]; 1128 CidTarget temp = (*sorted)[i];
1040 (*sorted)[i] = (*sorted)[largest_ix]; 1129 (*sorted)[i] = (*sorted)[largest_ix];
1041 (*sorted)[largest_ix] = temp; 1130 (*sorted)[largest_ix] = temp;
1042 } 1131 }
1043 } 1132 }
1044 } 1133 }
1045 1134
1046 } // namespace dart 1135 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698