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

Side by Side Diff: src/compiler/x64/instruction-selector-x64.cc

Issue 1414183006: [turbofan] Avoid unnecessary write barriers and improve code generation. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix typo. Created 5 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
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <algorithm> 5 #include <algorithm>
6 6
7 #include "src/base/adapters.h" 7 #include "src/base/adapters.h"
8 #include "src/compiler/instruction-selector-impl.h" 8 #include "src/compiler/instruction-selector-impl.h"
9 #include "src/compiler/node-matchers.h" 9 #include "src/compiler/node-matchers.h"
10 #include "src/compiler/node-properties.h" 10 #include "src/compiler/node-properties.h"
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 } 150 }
151 151
152 152
153 void InstructionSelector::VisitStore(Node* node) { 153 void InstructionSelector::VisitStore(Node* node) {
154 X64OperandGenerator g(this); 154 X64OperandGenerator g(this);
155 Node* base = node->InputAt(0); 155 Node* base = node->InputAt(0);
156 Node* index = node->InputAt(1); 156 Node* index = node->InputAt(1);
157 Node* value = node->InputAt(2); 157 Node* value = node->InputAt(2);
158 158
159 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); 159 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node);
160 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind();
160 MachineType rep = RepresentationOf(store_rep.machine_type()); 161 MachineType rep = RepresentationOf(store_rep.machine_type());
161 if (store_rep.write_barrier_kind() == kFullWriteBarrier) { 162
163 if (write_barrier_kind != kNoWriteBarrier) {
162 DCHECK_EQ(kRepTagged, rep); 164 DCHECK_EQ(kRepTagged, rep);
163 // TODO(dcarney): refactor RecordWrite function to take temp registers 165 AddressingMode addressing_mode;
164 // and pass them here instead of using fixed regs 166 InstructionOperand inputs[3];
167 size_t input_count = 0;
168 inputs[input_count++] = g.UseUniqueRegister(base);
165 if (g.CanBeImmediate(index)) { 169 if (g.CanBeImmediate(index)) {
166 InstructionOperand temps[] = {g.TempRegister(rcx), g.TempRegister()}; 170 inputs[input_count++] = g.UseImmediate(index);
167 Emit(kX64StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, rbx), 171 addressing_mode = kMode_MRI;
168 g.UseImmediate(index), g.UseFixed(value, rcx), arraysize(temps),
169 temps);
170 } else { 172 } else {
171 InstructionOperand temps[] = {g.TempRegister(rcx), g.TempRegister(rdx)}; 173 inputs[input_count++] = g.UseUniqueRegister(index);
172 Emit(kX64StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, rbx), 174 addressing_mode = kMode_MR1;
173 g.UseFixed(index, rcx), g.UseFixed(value, rdx), arraysize(temps),
174 temps);
175 } 175 }
176 return; 176 inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier)
177 ? g.UseRegister(value)
178 : g.UseUniqueRegister(value);
179 RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny;
180 switch (write_barrier_kind) {
181 case kNoWriteBarrier:
182 UNREACHABLE();
183 break;
184 case kMapWriteBarrier:
185 record_write_mode = RecordWriteMode::kValueIsMap;
186 break;
187 case kPointerWriteBarrier:
188 record_write_mode = RecordWriteMode::kValueIsPointer;
189 break;
190 case kFullWriteBarrier:
191 record_write_mode = RecordWriteMode::kValueIsAny;
192 break;
193 }
194 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()};
195 size_t const temp_count = arraysize(temps);
196 InstructionCode code = kArchStoreWithWriteBarrier;
197 code |= AddressingModeField::encode(addressing_mode);
198 code |= MiscField::encode(static_cast<int>(record_write_mode));
199 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps);
200 } else {
201 ArchOpcode opcode;
202 switch (rep) {
203 case kRepFloat32:
204 opcode = kX64Movss;
205 break;
206 case kRepFloat64:
207 opcode = kX64Movsd;
208 break;
209 case kRepBit: // Fall through.
210 case kRepWord8:
211 opcode = kX64Movb;
212 break;
213 case kRepWord16:
214 opcode = kX64Movw;
215 break;
216 case kRepWord32:
217 opcode = kX64Movl;
218 break;
219 case kRepTagged: // Fall through.
220 case kRepWord64:
221 opcode = kX64Movq;
222 break;
223 default:
224 UNREACHABLE();
225 return;
226 }
227 InstructionOperand inputs[4];
228 size_t input_count = 0;
229 AddressingMode addressing_mode =
230 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
231 InstructionCode code =
232 opcode | AddressingModeField::encode(addressing_mode);
233 InstructionOperand value_operand =
234 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value);
235 inputs[input_count++] = value_operand;
236 Emit(code, 0, static_cast<InstructionOperand*>(NULL), input_count, inputs);
177 } 237 }
178 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind());
179
180 ArchOpcode opcode;
181 switch (rep) {
182 case kRepFloat32:
183 opcode = kX64Movss;
184 break;
185 case kRepFloat64:
186 opcode = kX64Movsd;
187 break;
188 case kRepBit: // Fall through.
189 case kRepWord8:
190 opcode = kX64Movb;
191 break;
192 case kRepWord16:
193 opcode = kX64Movw;
194 break;
195 case kRepWord32:
196 opcode = kX64Movl;
197 break;
198 case kRepTagged: // Fall through.
199 case kRepWord64:
200 opcode = kX64Movq;
201 break;
202 default:
203 UNREACHABLE();
204 return;
205 }
206 InstructionOperand inputs[4];
207 size_t input_count = 0;
208 AddressingMode mode =
209 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
210 InstructionCode code = opcode | AddressingModeField::encode(mode);
211 InstructionOperand value_operand =
212 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value);
213 inputs[input_count++] = value_operand;
214 Emit(code, 0, static_cast<InstructionOperand*>(NULL), input_count, inputs);
215 } 238 }
216 239
217 240
218 void InstructionSelector::VisitCheckedLoad(Node* node) { 241 void InstructionSelector::VisitCheckedLoad(Node* node) {
219 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); 242 MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
220 MachineType typ = TypeOf(OpParameter<MachineType>(node)); 243 MachineType typ = TypeOf(OpParameter<MachineType>(node));
221 X64OperandGenerator g(this); 244 X64OperandGenerator g(this);
222 Node* const buffer = node->InputAt(0); 245 Node* const buffer = node->InputAt(0);
223 Node* const offset = node->InputAt(1); 246 Node* const offset = node->InputAt(1);
224 Node* const length = node->InputAt(2); 247 Node* const length = node->InputAt(2);
(...skipping 1388 matching lines...) Expand 10 before | Expand all | Expand 10 after
1613 if (CpuFeatures::IsSupported(SSE4_1)) { 1636 if (CpuFeatures::IsSupported(SSE4_1)) {
1614 flags |= MachineOperatorBuilder::kFloat64RoundDown | 1637 flags |= MachineOperatorBuilder::kFloat64RoundDown |
1615 MachineOperatorBuilder::kFloat64RoundTruncate; 1638 MachineOperatorBuilder::kFloat64RoundTruncate;
1616 } 1639 }
1617 return flags; 1640 return flags;
1618 } 1641 }
1619 1642
1620 } // namespace compiler 1643 } // namespace compiler
1621 } // namespace internal 1644 } // namespace internal
1622 } // namespace v8 1645 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698