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

Side by Side Diff: src/compiler/ia32/code-generator-ia32.cc

Issue 1242303005: [turbofan]: Elide extra move when accessing stack or frame register (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: src/compiler/code-generator.cc Created 5 years, 5 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
« no previous file with comments | « src/compiler/code-generator-impl.h ('k') | src/compiler/instruction.h » ('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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 "src/compiler/code-generator.h" 5 #include "src/compiler/code-generator.h"
6 6
7 #include "src/compiler/code-generator-impl.h" 7 #include "src/compiler/code-generator-impl.h"
8 #include "src/compiler/gap-resolver.h" 8 #include "src/compiler/gap-resolver.h"
9 #include "src/compiler/node-matchers.h" 9 #include "src/compiler/node-matchers.h"
10 #include "src/ia32/assembler-ia32.h" 10 #include "src/ia32/assembler-ia32.h"
(...skipping 20 matching lines...) Expand all
31 return ToOperand(instr_->InputAt(index), extra); 31 return ToOperand(instr_->InputAt(index), extra);
32 } 32 }
33 33
34 Immediate InputImmediate(size_t index) { 34 Immediate InputImmediate(size_t index) {
35 return ToImmediate(instr_->InputAt(index)); 35 return ToImmediate(instr_->InputAt(index));
36 } 36 }
37 37
38 Operand OutputOperand() { return ToOperand(instr_->Output()); } 38 Operand OutputOperand() { return ToOperand(instr_->Output()); }
39 39
40 Operand ToOperand(InstructionOperand* op, int extra = 0) { 40 Operand ToOperand(InstructionOperand* op, int extra = 0) {
41 if (op->IsRegister()) { 41 if (op->GeneratesRegister()) {
42 DCHECK(extra == 0); 42 DCHECK(extra == 0);
43 return Operand(ToRegister(op)); 43 return Operand(ToRegister(op));
44 } else if (op->IsDoubleRegister()) { 44 } else if (op->IsDoubleRegister()) {
45 DCHECK(extra == 0); 45 DCHECK(extra == 0);
46 return Operand(ToDoubleRegister(op)); 46 return Operand(ToDoubleRegister(op));
47 } 47 }
48 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); 48 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
49 // The linkage computes where all spill slots are located. 49 // The linkage computes where all spill slots are located.
50 FrameOffset offset = linkage()->GetFrameOffset( 50 FrameOffset offset = linkage()->GetFrameOffset(
51 AllocatedOperand::cast(op)->index(), frame(), extra); 51 AllocatedOperand::cast(op)->index(), frame(), extra);
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 XMMRegister const input_; 215 XMMRegister const input_;
216 }; 216 };
217 217
218 } // namespace 218 } // namespace
219 219
220 220
221 #define ASSEMBLE_CHECKED_LOAD_FLOAT(asm_instr) \ 221 #define ASSEMBLE_CHECKED_LOAD_FLOAT(asm_instr) \
222 do { \ 222 do { \
223 auto result = i.OutputDoubleRegister(); \ 223 auto result = i.OutputDoubleRegister(); \
224 auto offset = i.InputRegister(0); \ 224 auto offset = i.InputRegister(0); \
225 if (instr->InputAt(1)->IsRegister()) { \ 225 if (instr->InputAt(1)->GeneratesRegister()) { \
226 __ cmp(offset, i.InputRegister(1)); \ 226 __ cmp(offset, i.InputRegister(1)); \
227 } else { \ 227 } else { \
228 __ cmp(offset, i.InputImmediate(1)); \ 228 __ cmp(offset, i.InputImmediate(1)); \
229 } \ 229 } \
230 OutOfLineCode* ool = new (zone()) OutOfLineLoadFloat(this, result); \ 230 OutOfLineCode* ool = new (zone()) OutOfLineLoadFloat(this, result); \
231 __ j(above_equal, ool->entry()); \ 231 __ j(above_equal, ool->entry()); \
232 __ asm_instr(result, i.MemoryOperand(2)); \ 232 __ asm_instr(result, i.MemoryOperand(2)); \
233 __ bind(ool->exit()); \ 233 __ bind(ool->exit()); \
234 } while (false) 234 } while (false)
235 235
236 236
237 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \ 237 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \
238 do { \ 238 do { \
239 auto result = i.OutputRegister(); \ 239 auto result = i.OutputRegister(); \
240 auto offset = i.InputRegister(0); \ 240 auto offset = i.InputRegister(0); \
241 if (instr->InputAt(1)->IsRegister()) { \ 241 if (instr->InputAt(1)->GeneratesRegister()) { \
242 __ cmp(offset, i.InputRegister(1)); \ 242 __ cmp(offset, i.InputRegister(1)); \
243 } else { \ 243 } else { \
244 __ cmp(offset, i.InputImmediate(1)); \ 244 __ cmp(offset, i.InputImmediate(1)); \
245 } \ 245 } \
246 OutOfLineCode* ool = new (zone()) OutOfLineLoadInteger(this, result); \ 246 OutOfLineCode* ool = new (zone()) OutOfLineLoadInteger(this, result); \
247 __ j(above_equal, ool->entry()); \ 247 __ j(above_equal, ool->entry()); \
248 __ asm_instr(result, i.MemoryOperand(2)); \ 248 __ asm_instr(result, i.MemoryOperand(2)); \
249 __ bind(ool->exit()); \ 249 __ bind(ool->exit()); \
250 } while (false) 250 } while (false)
251 251
252 252
253 #define ASSEMBLE_CHECKED_STORE_FLOAT(asm_instr) \ 253 #define ASSEMBLE_CHECKED_STORE_FLOAT(asm_instr) \
254 do { \ 254 do { \
255 auto offset = i.InputRegister(0); \ 255 auto offset = i.InputRegister(0); \
256 if (instr->InputAt(1)->IsRegister()) { \ 256 if (instr->InputAt(1)->GeneratesRegister()) { \
257 __ cmp(offset, i.InputRegister(1)); \ 257 __ cmp(offset, i.InputRegister(1)); \
258 } else { \ 258 } else { \
259 __ cmp(offset, i.InputImmediate(1)); \ 259 __ cmp(offset, i.InputImmediate(1)); \
260 } \ 260 } \
261 Label done; \ 261 Label done; \
262 __ j(above_equal, &done, Label::kNear); \ 262 __ j(above_equal, &done, Label::kNear); \
263 __ asm_instr(i.MemoryOperand(3), i.InputDoubleRegister(2)); \ 263 __ asm_instr(i.MemoryOperand(3), i.InputDoubleRegister(2)); \
264 __ bind(&done); \ 264 __ bind(&done); \
265 } while (false) 265 } while (false)
266 266
267 267
268 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ 268 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \
269 do { \ 269 do { \
270 auto offset = i.InputRegister(0); \ 270 auto offset = i.InputRegister(0); \
271 if (instr->InputAt(1)->IsRegister()) { \ 271 if (instr->InputAt(1)->GeneratesRegister()) { \
272 __ cmp(offset, i.InputRegister(1)); \ 272 __ cmp(offset, i.InputRegister(1)); \
273 } else { \ 273 } else { \
274 __ cmp(offset, i.InputImmediate(1)); \ 274 __ cmp(offset, i.InputImmediate(1)); \
275 } \ 275 } \
276 Label done; \ 276 Label done; \
277 __ j(above_equal, &done, Label::kNear); \ 277 __ j(above_equal, &done, Label::kNear); \
278 if (instr->InputAt(2)->IsRegister()) { \ 278 if (instr->InputAt(2)->GeneratesRegister()) { \
279 __ asm_instr(i.MemoryOperand(3), i.InputRegister(2)); \ 279 __ asm_instr(i.MemoryOperand(3), i.InputRegister(2)); \
280 } else { \ 280 } else { \
281 __ asm_instr(i.MemoryOperand(3), i.InputImmediate(2)); \ 281 __ asm_instr(i.MemoryOperand(3), i.InputImmediate(2)); \
282 } \ 282 } \
283 __ bind(&done); \ 283 __ bind(&done); \
284 } while (false) 284 } while (false)
285 285
286 286
287 void CodeGenerator::AssembleDeconstructActivationRecord() { 287 void CodeGenerator::AssembleDeconstructActivationRecord() {
288 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); 288 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
(...skipping 1065 matching lines...) Expand 10 before | Expand all | Expand 10 after
1354 __ ret(0); 1354 __ ret(0);
1355 } 1355 }
1356 } 1356 }
1357 1357
1358 1358
1359 void CodeGenerator::AssembleMove(InstructionOperand* source, 1359 void CodeGenerator::AssembleMove(InstructionOperand* source,
1360 InstructionOperand* destination) { 1360 InstructionOperand* destination) {
1361 IA32OperandConverter g(this, NULL); 1361 IA32OperandConverter g(this, NULL);
1362 // Dispatch on the source and destination operand kinds. Not all 1362 // Dispatch on the source and destination operand kinds. Not all
1363 // combinations are possible. 1363 // combinations are possible.
1364 if (source->IsRegister()) { 1364 if (source->GeneratesRegister()) {
1365 DCHECK(destination->IsRegister() || destination->IsStackSlot()); 1365 DCHECK(destination->GeneratesRegister() || destination->IsStackSlot());
1366 Register src = g.ToRegister(source); 1366 Register src = g.ToRegister(source);
1367 Operand dst = g.ToOperand(destination); 1367 Operand dst = g.ToOperand(destination);
1368 __ mov(dst, src); 1368 __ mov(dst, src);
1369 } else if (source->IsStackSlot()) { 1369 } else if (source->IsStackSlot()) {
1370 DCHECK(destination->IsRegister() || destination->IsStackSlot()); 1370 DCHECK(destination->GeneratesRegister() || destination->IsStackSlot());
1371 Operand src = g.ToOperand(source); 1371 Operand src = g.ToOperand(source);
1372 if (destination->IsRegister()) { 1372 if (destination->GeneratesRegister()) {
1373 Register dst = g.ToRegister(destination); 1373 Register dst = g.ToRegister(destination);
1374 __ mov(dst, src); 1374 __ mov(dst, src);
1375 } else { 1375 } else {
1376 Operand dst = g.ToOperand(destination); 1376 Operand dst = g.ToOperand(destination);
1377 __ push(src); 1377 __ push(src);
1378 __ pop(dst); 1378 __ pop(dst);
1379 } 1379 }
1380 } else if (source->IsConstant()) { 1380 } else if (source->IsConstant()) {
1381 Constant src_constant = g.ToConstant(source); 1381 Constant src_constant = g.ToConstant(source);
1382 if (src_constant.type() == Constant::kHeapObject) { 1382 if (src_constant.type() == Constant::kHeapObject) {
1383 Handle<HeapObject> src = src_constant.ToHeapObject(); 1383 Handle<HeapObject> src = src_constant.ToHeapObject();
1384 int offset; 1384 int offset;
1385 if (IsMaterializableFromFrame(src, &offset)) { 1385 if (IsMaterializableFromFrame(src, &offset)) {
1386 if (destination->IsRegister()) { 1386 if (destination->GeneratesRegister()) {
1387 Register dst = g.ToRegister(destination); 1387 Register dst = g.ToRegister(destination);
1388 __ mov(dst, Operand(ebp, offset)); 1388 __ mov(dst, Operand(ebp, offset));
1389 } else { 1389 } else {
1390 DCHECK(destination->IsStackSlot()); 1390 DCHECK(destination->IsStackSlot());
1391 Operand dst = g.ToOperand(destination); 1391 Operand dst = g.ToOperand(destination);
1392 __ push(Operand(ebp, offset)); 1392 __ push(Operand(ebp, offset));
1393 __ pop(dst); 1393 __ pop(dst);
1394 } 1394 }
1395 } else if (destination->IsRegister()) { 1395 } else if (destination->GeneratesRegister()) {
1396 Register dst = g.ToRegister(destination); 1396 Register dst = g.ToRegister(destination);
1397 __ LoadHeapObject(dst, src); 1397 __ LoadHeapObject(dst, src);
1398 } else { 1398 } else {
1399 DCHECK(destination->IsStackSlot()); 1399 DCHECK(destination->IsStackSlot());
1400 Operand dst = g.ToOperand(destination); 1400 Operand dst = g.ToOperand(destination);
1401 AllowDeferredHandleDereference embedding_raw_address; 1401 AllowDeferredHandleDereference embedding_raw_address;
1402 if (isolate()->heap()->InNewSpace(*src)) { 1402 if (isolate()->heap()->InNewSpace(*src)) {
1403 __ PushHeapObject(src); 1403 __ PushHeapObject(src);
1404 __ pop(dst); 1404 __ pop(dst);
1405 } else { 1405 } else {
1406 __ mov(dst, src); 1406 __ mov(dst, src);
1407 } 1407 }
1408 } 1408 }
1409 } else if (destination->IsRegister()) { 1409 } else if (destination->GeneratesRegister()) {
1410 Register dst = g.ToRegister(destination); 1410 Register dst = g.ToRegister(destination);
1411 __ Move(dst, g.ToImmediate(source)); 1411 __ Move(dst, g.ToImmediate(source));
1412 } else if (destination->IsStackSlot()) { 1412 } else if (destination->IsStackSlot()) {
1413 Operand dst = g.ToOperand(destination); 1413 Operand dst = g.ToOperand(destination);
1414 __ Move(dst, g.ToImmediate(source)); 1414 __ Move(dst, g.ToImmediate(source));
1415 } else if (src_constant.type() == Constant::kFloat32) { 1415 } else if (src_constant.type() == Constant::kFloat32) {
1416 // TODO(turbofan): Can we do better here? 1416 // TODO(turbofan): Can we do better here?
1417 uint32_t src = bit_cast<uint32_t>(src_constant.ToFloat32()); 1417 uint32_t src = bit_cast<uint32_t>(src_constant.ToFloat32());
1418 if (destination->IsDoubleRegister()) { 1418 if (destination->IsDoubleRegister()) {
1419 XMMRegister dst = g.ToDoubleRegister(destination); 1419 XMMRegister dst = g.ToDoubleRegister(destination);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1464 UNREACHABLE(); 1464 UNREACHABLE();
1465 } 1465 }
1466 } 1466 }
1467 1467
1468 1468
1469 void CodeGenerator::AssembleSwap(InstructionOperand* source, 1469 void CodeGenerator::AssembleSwap(InstructionOperand* source,
1470 InstructionOperand* destination) { 1470 InstructionOperand* destination) {
1471 IA32OperandConverter g(this, NULL); 1471 IA32OperandConverter g(this, NULL);
1472 // Dispatch on the source and destination operand kinds. Not all 1472 // Dispatch on the source and destination operand kinds. Not all
1473 // combinations are possible. 1473 // combinations are possible.
1474 if (source->IsRegister() && destination->IsRegister()) { 1474 if (source->GeneratesRegister() && destination->GeneratesRegister()) {
1475 // Register-register. 1475 // Register-register.
1476 Register src = g.ToRegister(source); 1476 Register src = g.ToRegister(source);
1477 Register dst = g.ToRegister(destination); 1477 Register dst = g.ToRegister(destination);
1478 __ xchg(dst, src); 1478 __ xchg(dst, src);
1479 } else if (source->IsRegister() && destination->IsStackSlot()) { 1479 } else if (source->GeneratesRegister() && destination->IsStackSlot()) {
1480 // Register-memory. 1480 // Register-memory.
1481 __ xchg(g.ToRegister(source), g.ToOperand(destination)); 1481 __ xchg(g.ToRegister(source), g.ToOperand(destination));
1482 } else if (source->IsStackSlot() && destination->IsStackSlot()) { 1482 } else if (source->IsStackSlot() && destination->IsStackSlot()) {
1483 // Memory-memory. 1483 // Memory-memory.
1484 Operand src = g.ToOperand(source); 1484 Operand src = g.ToOperand(source);
1485 Operand dst = g.ToOperand(destination); 1485 Operand dst = g.ToOperand(destination);
1486 __ push(dst); 1486 __ push(dst);
1487 __ push(src); 1487 __ push(src);
1488 __ pop(dst); 1488 __ pop(dst);
1489 __ pop(src); 1489 __ pop(src);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1541 __ Nop(padding_size); 1541 __ Nop(padding_size);
1542 } 1542 }
1543 } 1543 }
1544 } 1544 }
1545 1545
1546 #undef __ 1546 #undef __
1547 1547
1548 } // namespace compiler 1548 } // namespace compiler
1549 } // namespace internal 1549 } // namespace internal
1550 } // namespace v8 1550 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/code-generator-impl.h ('k') | src/compiler/instruction.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698