| OLD | NEW |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/factory.h" | 7 #include "src/factory.h" |
| 8 #include "src/interpreter/bytecode-label.h" | 8 #include "src/interpreter/bytecode-label.h" |
| 9 #include "src/interpreter/bytecode-peephole-optimizer.h" | 9 #include "src/interpreter/bytecode-peephole-optimizer.h" |
| 10 #include "src/objects-inl.h" | 10 #include "src/objects-inl.h" |
| 11 #include "src/objects.h" | 11 #include "src/objects.h" |
| 12 #include "test/unittests/test-utils.h" | 12 #include "test/unittests/test-utils.h" |
| 13 | 13 |
| 14 namespace v8 { | 14 namespace v8 { |
| 15 namespace internal { | 15 namespace internal { |
| 16 namespace interpreter { | 16 namespace interpreter { |
| 17 | 17 |
| 18 class BytecodePeepholeOptimizerTest : public BytecodePipelineStage, | 18 class BytecodePeepholeOptimizerTest : public BytecodePipelineStage, |
| 19 public TestWithIsolateAndZone { | 19 public TestWithIsolateAndZone { |
| 20 public: | 20 public: |
| 21 BytecodePeepholeOptimizerTest() | 21 BytecodePeepholeOptimizerTest() : peephole_optimizer_(this) {} |
| 22 : peephole_optimizer_(this), last_written_(Bytecode::kIllegal) {} | |
| 23 ~BytecodePeepholeOptimizerTest() override {} | 22 ~BytecodePeepholeOptimizerTest() override {} |
| 24 | 23 |
| 25 void Reset() { | 24 void Reset() { |
| 26 last_written_.set_bytecode(Bytecode::kIllegal); | 25 last_written_.set_bytecode(Bytecode::kIllegal); |
| 27 write_count_ = 0; | 26 write_count_ = 0; |
| 28 } | 27 } |
| 29 | 28 |
| 30 void Write(BytecodeNode* node) override { | 29 void Write(BytecodeNode* node) override { |
| 31 write_count_++; | 30 write_count_++; |
| 32 last_written_.Clone(node); | 31 last_written_.Clone(node); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 // Sanity tests. | 64 // Sanity tests. |
| 66 | 65 |
| 67 TEST_F(BytecodePeepholeOptimizerTest, FlushOnJump) { | 66 TEST_F(BytecodePeepholeOptimizerTest, FlushOnJump) { |
| 68 CHECK_EQ(write_count(), 0); | 67 CHECK_EQ(write_count(), 0); |
| 69 | 68 |
| 70 BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand(), 1); | 69 BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand(), 1); |
| 71 optimizer()->Write(&add); | 70 optimizer()->Write(&add); |
| 72 CHECK_EQ(write_count(), 0); | 71 CHECK_EQ(write_count(), 0); |
| 73 | 72 |
| 74 BytecodeLabel target; | 73 BytecodeLabel target; |
| 75 BytecodeNode jump(Bytecode::kJump, 0, nullptr); | 74 BytecodeNode jump(Bytecode::kJump, 0); |
| 76 optimizer()->WriteJump(&jump, &target); | 75 optimizer()->WriteJump(&jump, &target); |
| 77 CHECK_EQ(write_count(), 2); | 76 CHECK_EQ(write_count(), 2); |
| 78 CHECK_EQ(jump, last_written()); | 77 CHECK_EQ(jump, last_written()); |
| 79 } | 78 } |
| 80 | 79 |
| 81 TEST_F(BytecodePeepholeOptimizerTest, FlushOnBind) { | 80 TEST_F(BytecodePeepholeOptimizerTest, FlushOnBind) { |
| 82 CHECK_EQ(write_count(), 0); | 81 CHECK_EQ(write_count(), 0); |
| 83 | 82 |
| 84 BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand(), 1); | 83 BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand(), 1); |
| 85 optimizer()->Write(&add); | 84 optimizer()->Write(&add); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 97 BytecodeNode nop(Bytecode::kNop); | 96 BytecodeNode nop(Bytecode::kNop); |
| 98 optimizer()->Write(&nop); | 97 optimizer()->Write(&nop); |
| 99 BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand(), 1); | 98 BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand(), 1); |
| 100 optimizer()->Write(&add); | 99 optimizer()->Write(&add); |
| 101 Flush(); | 100 Flush(); |
| 102 CHECK_EQ(write_count(), 1); | 101 CHECK_EQ(write_count(), 1); |
| 103 CHECK_EQ(add, last_written()); | 102 CHECK_EQ(add, last_written()); |
| 104 } | 103 } |
| 105 | 104 |
| 106 TEST_F(BytecodePeepholeOptimizerTest, ElideExpressionNop) { | 105 TEST_F(BytecodePeepholeOptimizerTest, ElideExpressionNop) { |
| 107 BytecodeSourceInfo source_info(3, false); | 106 BytecodeNode nop(Bytecode::kNop); |
| 108 BytecodeNode nop(Bytecode::kNop, &source_info); | 107 nop.source_info().MakeExpressionPosition(3); |
| 109 optimizer()->Write(&nop); | 108 optimizer()->Write(&nop); |
| 110 BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand(), 1); | 109 BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand(), 1); |
| 111 optimizer()->Write(&add); | 110 optimizer()->Write(&add); |
| 112 Flush(); | 111 Flush(); |
| 113 CHECK_EQ(write_count(), 1); | 112 CHECK_EQ(write_count(), 1); |
| 114 CHECK_EQ(add, last_written()); | 113 CHECK_EQ(add, last_written()); |
| 115 } | 114 } |
| 116 | 115 |
| 117 TEST_F(BytecodePeepholeOptimizerTest, KeepStatementNop) { | 116 TEST_F(BytecodePeepholeOptimizerTest, KeepStatementNop) { |
| 118 BytecodeSourceInfo source_info(3, true); | 117 BytecodeNode nop(Bytecode::kNop); |
| 119 BytecodeNode nop(Bytecode::kNop, &source_info); | 118 nop.source_info().MakeStatementPosition(3); |
| 120 optimizer()->Write(&nop); | 119 optimizer()->Write(&nop); |
| 121 source_info.MakeExpressionPosition(3); | 120 BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand(), 1); |
| 122 BytecodeNode add(Bytecode::kAdd, Register(0).ToOperand(), 1, &source_info); | 121 add.source_info().MakeExpressionPosition(3); |
| 123 optimizer()->Write(&add); | 122 optimizer()->Write(&add); |
| 124 Flush(); | 123 Flush(); |
| 125 CHECK_EQ(write_count(), 2); | 124 CHECK_EQ(write_count(), 2); |
| 126 CHECK_EQ(add, last_written()); | 125 CHECK_EQ(add, last_written()); |
| 127 } | 126 } |
| 128 | 127 |
| 129 // Tests covering BytecodePeepholeOptimizer::UpdateCurrentBytecode(). | 128 // Tests covering BytecodePeepholeOptimizer::UpdateCurrentBytecode(). |
| 130 | 129 |
| 131 TEST_F(BytecodePeepholeOptimizerTest, KeepJumpIfToBooleanTrue) { | 130 TEST_F(BytecodePeepholeOptimizerTest, KeepJumpIfToBooleanTrue) { |
| 132 BytecodeNode first(Bytecode::kLdaNull); | 131 BytecodeNode first(Bytecode::kLdaNull); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 optimizer()->Write(&first); | 197 optimizer()->Write(&first); |
| 199 optimizer()->Write(&second); | 198 optimizer()->Write(&second); |
| 200 CHECK_EQ(write_count(), 0); | 199 CHECK_EQ(write_count(), 0); |
| 201 Flush(); | 200 Flush(); |
| 202 CHECK_EQ(write_count(), 1); | 201 CHECK_EQ(write_count(), 1); |
| 203 CHECK_EQ(last_written(), first); | 202 CHECK_EQ(last_written(), first); |
| 204 } | 203 } |
| 205 | 204 |
| 206 TEST_F(BytecodePeepholeOptimizerTest, StarRxLdarRxStatement) { | 205 TEST_F(BytecodePeepholeOptimizerTest, StarRxLdarRxStatement) { |
| 207 BytecodeNode first(Bytecode::kStar, Register(0).ToOperand()); | 206 BytecodeNode first(Bytecode::kStar, Register(0).ToOperand()); |
| 208 BytecodeSourceInfo source_info(3, true); | 207 BytecodeNode second(Bytecode::kLdar, Register(0).ToOperand()); |
| 209 BytecodeNode second(Bytecode::kLdar, Register(0).ToOperand(), &source_info); | 208 second.source_info().MakeStatementPosition(0); |
| 210 optimizer()->Write(&first); | 209 optimizer()->Write(&first); |
| 211 CHECK_EQ(write_count(), 0); | 210 CHECK_EQ(write_count(), 0); |
| 212 optimizer()->Write(&second); | 211 optimizer()->Write(&second); |
| 213 CHECK_EQ(write_count(), 1); | 212 CHECK_EQ(write_count(), 1); |
| 214 CHECK_EQ(last_written(), first); | 213 CHECK_EQ(last_written(), first); |
| 215 Flush(); | 214 Flush(); |
| 216 CHECK_EQ(write_count(), 2); | 215 CHECK_EQ(write_count(), 2); |
| 217 CHECK_EQ(last_written().bytecode(), Bytecode::kNop); | 216 CHECK_EQ(last_written().bytecode(), Bytecode::kNop); |
| 218 CHECK_EQ(last_written().source_info(), second.source_info()); | 217 CHECK_EQ(last_written().source_info(), second.source_info()); |
| 219 } | 218 } |
| 220 | 219 |
| 221 TEST_F(BytecodePeepholeOptimizerTest, StarRxLdarRxStatementStarRy) { | 220 TEST_F(BytecodePeepholeOptimizerTest, StarRxLdarRxStatementStarRy) { |
| 222 BytecodeLabel label; | 221 BytecodeLabel label; |
| 223 BytecodeNode first(Bytecode::kStar, Register(0).ToOperand()); | 222 BytecodeNode first(Bytecode::kStar, Register(0).ToOperand()); |
| 224 BytecodeSourceInfo source_info(0, true); | 223 BytecodeNode second(Bytecode::kLdar, Register(0).ToOperand()); |
| 225 BytecodeNode second(Bytecode::kLdar, Register(0).ToOperand(), &source_info); | |
| 226 BytecodeNode third(Bytecode::kStar, Register(3).ToOperand()); | 224 BytecodeNode third(Bytecode::kStar, Register(3).ToOperand()); |
| 225 second.source_info().MakeStatementPosition(0); |
| 227 optimizer()->Write(&first); | 226 optimizer()->Write(&first); |
| 228 CHECK_EQ(write_count(), 0); | 227 CHECK_EQ(write_count(), 0); |
| 229 optimizer()->Write(&second); | 228 optimizer()->Write(&second); |
| 230 CHECK_EQ(write_count(), 1); | 229 CHECK_EQ(write_count(), 1); |
| 231 CHECK_EQ(last_written(), first); | 230 CHECK_EQ(last_written(), first); |
| 232 optimizer()->Write(&third); | 231 optimizer()->Write(&third); |
| 233 CHECK_EQ(write_count(), 1); | 232 CHECK_EQ(write_count(), 1); |
| 234 Flush(); | 233 Flush(); |
| 235 CHECK_EQ(write_count(), 2); | 234 CHECK_EQ(write_count(), 2); |
| 236 CHECK_EQ(last_written(), third); | 235 CHECK_EQ(last_written(), third); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 271 optimizer()->Write(&first); | 270 optimizer()->Write(&first); |
| 272 CHECK_EQ(write_count(), 0); | 271 CHECK_EQ(write_count(), 0); |
| 273 optimizer()->Write(&second); | 272 optimizer()->Write(&second); |
| 274 CHECK_EQ(write_count(), 0); | 273 CHECK_EQ(write_count(), 0); |
| 275 Flush(); | 274 Flush(); |
| 276 CHECK_EQ(write_count(), 1); | 275 CHECK_EQ(write_count(), 1); |
| 277 CHECK_EQ(last_written(), second); | 276 CHECK_EQ(last_written(), second); |
| 278 } | 277 } |
| 279 | 278 |
| 280 TEST_F(BytecodePeepholeOptimizerTest, LdaTrueStatementLdaFalse) { | 279 TEST_F(BytecodePeepholeOptimizerTest, LdaTrueStatementLdaFalse) { |
| 281 BytecodeSourceInfo source_info(3, true); | 280 BytecodeNode first(Bytecode::kLdaTrue); |
| 282 BytecodeNode first(Bytecode::kLdaTrue, &source_info); | 281 first.source_info().MakeExpressionPosition(3); |
| 283 BytecodeNode second(Bytecode::kLdaFalse); | 282 BytecodeNode second(Bytecode::kLdaFalse); |
| 284 optimizer()->Write(&first); | 283 optimizer()->Write(&first); |
| 285 CHECK_EQ(write_count(), 0); | 284 CHECK_EQ(write_count(), 0); |
| 286 optimizer()->Write(&second); | 285 optimizer()->Write(&second); |
| 287 CHECK_EQ(write_count(), 0); | 286 CHECK_EQ(write_count(), 0); |
| 288 Flush(); | 287 Flush(); |
| 289 CHECK_EQ(write_count(), 1); | 288 CHECK_EQ(write_count(), 1); |
| 290 CHECK_EQ(last_written(), second); | 289 CHECK_EQ(last_written(), second); |
| 291 CHECK(second.source_info().is_statement()); | 290 CHECK(second.source_info().is_expression()); |
| 292 CHECK_EQ(second.source_info().source_position(), 3); | 291 CHECK_EQ(second.source_info().source_position(), 3); |
| 293 } | 292 } |
| 294 | 293 |
| 295 TEST_F(BytecodePeepholeOptimizerTest, NopStackCheck) { | 294 TEST_F(BytecodePeepholeOptimizerTest, NopStackCheck) { |
| 296 BytecodeNode first(Bytecode::kNop); | 295 BytecodeNode first(Bytecode::kNop); |
| 297 BytecodeNode second(Bytecode::kStackCheck, nullptr); | 296 BytecodeNode second(Bytecode::kStackCheck); |
| 298 optimizer()->Write(&first); | 297 optimizer()->Write(&first); |
| 299 CHECK_EQ(write_count(), 0); | 298 CHECK_EQ(write_count(), 0); |
| 300 optimizer()->Write(&second); | 299 optimizer()->Write(&second); |
| 301 CHECK_EQ(write_count(), 0); | 300 CHECK_EQ(write_count(), 0); |
| 302 Flush(); | 301 Flush(); |
| 303 CHECK_EQ(write_count(), 1); | 302 CHECK_EQ(write_count(), 1); |
| 304 CHECK_EQ(last_written(), second); | 303 CHECK_EQ(last_written(), second); |
| 305 } | 304 } |
| 306 | 305 |
| 307 TEST_F(BytecodePeepholeOptimizerTest, NopStatementStackCheck) { | 306 TEST_F(BytecodePeepholeOptimizerTest, NopStatementStackCheck) { |
| 308 BytecodeSourceInfo source_info(3, true); | 307 BytecodeNode first(Bytecode::kNop); |
| 309 BytecodeNode first(Bytecode::kNop, &source_info); | 308 first.source_info().MakeExpressionPosition(3); |
| 310 BytecodeNode second(Bytecode::kStackCheck); | 309 BytecodeNode second(Bytecode::kStackCheck); |
| 311 optimizer()->Write(&first); | 310 optimizer()->Write(&first); |
| 312 CHECK_EQ(write_count(), 0); | 311 CHECK_EQ(write_count(), 0); |
| 313 optimizer()->Write(&second); | 312 optimizer()->Write(&second); |
| 314 CHECK_EQ(write_count(), 0); | 313 CHECK_EQ(write_count(), 0); |
| 315 Flush(); | 314 Flush(); |
| 316 CHECK_EQ(write_count(), 1); | 315 CHECK_EQ(write_count(), 1); |
| 317 BytecodeSourceInfo expected_source_info(3, true); | 316 second.source_info().MakeExpressionPosition( |
| 318 BytecodeNode expected(Bytecode::kStackCheck, &expected_source_info); | 317 first.source_info().source_position()); |
| 319 CHECK_EQ(last_written(), expected); | 318 CHECK_EQ(last_written(), second); |
| 320 } | 319 } |
| 321 | 320 |
| 322 // Tests covering BytecodePeepholeOptimizer::UpdateLastAndCurrentBytecodes(). | 321 // Tests covering BytecodePeepholeOptimizer::UpdateLastAndCurrentBytecodes(). |
| 323 | 322 |
| 324 TEST_F(BytecodePeepholeOptimizerTest, MergeLoadICStar) { | 323 TEST_F(BytecodePeepholeOptimizerTest, MergeLoadICStar) { |
| 325 const uint32_t operands[] = { | 324 const uint32_t operands[] = { |
| 326 static_cast<uint32_t>(Register(31).ToOperand()), 32, 33, | 325 static_cast<uint32_t>(Register(31).ToOperand()), 32, 33, |
| 327 static_cast<uint32_t>(Register(256).ToOperand())}; | 326 static_cast<uint32_t>(Register(256).ToOperand())}; |
| 328 const int expected_operand_count = static_cast<int>(arraysize(operands)); | 327 const int expected_operand_count = static_cast<int>(arraysize(operands)); |
| 329 | 328 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 346 Flush(); | 345 Flush(); |
| 347 CHECK_EQ(last_written().bytecode(), third.bytecode()); | 346 CHECK_EQ(last_written().bytecode(), third.bytecode()); |
| 348 } | 347 } |
| 349 | 348 |
| 350 TEST_F(BytecodePeepholeOptimizerTest, MergeLdaKeyedPropertyStar) { | 349 TEST_F(BytecodePeepholeOptimizerTest, MergeLdaKeyedPropertyStar) { |
| 351 const uint32_t operands[] = {static_cast<uint32_t>(Register(31).ToOperand()), | 350 const uint32_t operands[] = {static_cast<uint32_t>(Register(31).ToOperand()), |
| 352 9999997, | 351 9999997, |
| 353 static_cast<uint32_t>(Register(1).ToOperand())}; | 352 static_cast<uint32_t>(Register(1).ToOperand())}; |
| 354 const int expected_operand_count = static_cast<int>(arraysize(operands)); | 353 const int expected_operand_count = static_cast<int>(arraysize(operands)); |
| 355 | 354 |
| 356 BytecodeNode first(Bytecode::kLdaKeyedProperty, operands[0], operands[1], | 355 BytecodeNode first(Bytecode::kLdaKeyedProperty, operands[0], operands[1]); |
| 357 nullptr); | |
| 358 BytecodeNode second(Bytecode::kStar, operands[2]); | 356 BytecodeNode second(Bytecode::kStar, operands[2]); |
| 359 BytecodeNode third(Bytecode::kReturn); | 357 BytecodeNode third(Bytecode::kReturn); |
| 360 optimizer()->Write(&first); | 358 optimizer()->Write(&first); |
| 361 optimizer()->Write(&second); | 359 optimizer()->Write(&second); |
| 362 CHECK_EQ(write_count(), 1); | 360 CHECK_EQ(write_count(), 1); |
| 363 CHECK_EQ(last_written().bytecode(), Bytecode::kLdrKeyedProperty); | 361 CHECK_EQ(last_written().bytecode(), Bytecode::kLdrKeyedProperty); |
| 364 CHECK_EQ(last_written().operand_count(), expected_operand_count); | 362 CHECK_EQ(last_written().operand_count(), expected_operand_count); |
| 365 for (int i = 0; i < expected_operand_count; ++i) { | 363 for (int i = 0; i < expected_operand_count; ++i) { |
| 366 CHECK_EQ(last_written().operand(i), operands[i]); | 364 CHECK_EQ(last_written().operand(i), operands[i]); |
| 367 } | 365 } |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 452 Bytecode operator_replacement_pairs[][2] = { | 450 Bytecode operator_replacement_pairs[][2] = { |
| 453 {Bytecode::kAdd, Bytecode::kAddSmi}, | 451 {Bytecode::kAdd, Bytecode::kAddSmi}, |
| 454 {Bytecode::kSub, Bytecode::kSubSmi}, | 452 {Bytecode::kSub, Bytecode::kSubSmi}, |
| 455 {Bytecode::kBitwiseAnd, Bytecode::kBitwiseAndSmi}, | 453 {Bytecode::kBitwiseAnd, Bytecode::kBitwiseAndSmi}, |
| 456 {Bytecode::kBitwiseOr, Bytecode::kBitwiseOrSmi}, | 454 {Bytecode::kBitwiseOr, Bytecode::kBitwiseOrSmi}, |
| 457 {Bytecode::kShiftLeft, Bytecode::kShiftLeftSmi}, | 455 {Bytecode::kShiftLeft, Bytecode::kShiftLeftSmi}, |
| 458 {Bytecode::kShiftRight, Bytecode::kShiftRightSmi}}; | 456 {Bytecode::kShiftRight, Bytecode::kShiftRightSmi}}; |
| 459 | 457 |
| 460 for (auto operator_replacement : operator_replacement_pairs) { | 458 for (auto operator_replacement : operator_replacement_pairs) { |
| 461 uint32_t imm_operand = 17; | 459 uint32_t imm_operand = 17; |
| 462 BytecodeSourceInfo source_info(3, true); | 460 BytecodeNode first(Bytecode::kLdaSmi, imm_operand); |
| 463 BytecodeNode first(Bytecode::kLdaSmi, imm_operand, &source_info); | 461 first.source_info().Clone({3, true}); |
| 464 uint32_t reg_operand = Register(0).ToOperand(); | 462 uint32_t reg_operand = Register(0).ToOperand(); |
| 465 uint32_t idx_operand = 1; | 463 uint32_t idx_operand = 1; |
| 466 BytecodeNode second(operator_replacement[0], reg_operand, idx_operand); | 464 BytecodeNode second(operator_replacement[0], reg_operand, idx_operand); |
| 467 optimizer()->Write(&first); | 465 optimizer()->Write(&first); |
| 468 optimizer()->Write(&second); | 466 optimizer()->Write(&second); |
| 469 Flush(); | 467 Flush(); |
| 470 CHECK_EQ(write_count(), 1); | 468 CHECK_EQ(write_count(), 1); |
| 471 CHECK_EQ(last_written().bytecode(), operator_replacement[1]); | 469 CHECK_EQ(last_written().bytecode(), operator_replacement[1]); |
| 472 CHECK_EQ(last_written().operand_count(), 3); | 470 CHECK_EQ(last_written().operand_count(), 3); |
| 473 CHECK_EQ(last_written().operand(0), imm_operand); | 471 CHECK_EQ(last_written().operand(0), imm_operand); |
| 474 CHECK_EQ(last_written().operand(1), reg_operand); | 472 CHECK_EQ(last_written().operand(1), reg_operand); |
| 475 CHECK_EQ(last_written().operand(2), idx_operand); | 473 CHECK_EQ(last_written().operand(2), idx_operand); |
| 476 CHECK_EQ(last_written().source_info(), first.source_info()); | 474 CHECK_EQ(last_written().source_info(), first.source_info()); |
| 477 Reset(); | 475 Reset(); |
| 478 } | 476 } |
| 479 } | 477 } |
| 480 | 478 |
| 481 TEST_F(BytecodePeepholeOptimizerTest, NotMergingLdaSmiWithBinaryOp) { | 479 TEST_F(BytecodePeepholeOptimizerTest, NotMergingLdaSmiWithBinaryOp) { |
| 482 Bytecode operator_replacement_pairs[][2] = { | 480 Bytecode operator_replacement_pairs[][2] = { |
| 483 {Bytecode::kAdd, Bytecode::kAddSmi}, | 481 {Bytecode::kAdd, Bytecode::kAddSmi}, |
| 484 {Bytecode::kSub, Bytecode::kSubSmi}, | 482 {Bytecode::kSub, Bytecode::kSubSmi}, |
| 485 {Bytecode::kBitwiseAnd, Bytecode::kBitwiseAndSmi}, | 483 {Bytecode::kBitwiseAnd, Bytecode::kBitwiseAndSmi}, |
| 486 {Bytecode::kBitwiseOr, Bytecode::kBitwiseOrSmi}, | 484 {Bytecode::kBitwiseOr, Bytecode::kBitwiseOrSmi}, |
| 487 {Bytecode::kShiftLeft, Bytecode::kShiftLeftSmi}, | 485 {Bytecode::kShiftLeft, Bytecode::kShiftLeftSmi}, |
| 488 {Bytecode::kShiftRight, Bytecode::kShiftRightSmi}}; | 486 {Bytecode::kShiftRight, Bytecode::kShiftRightSmi}}; |
| 489 | 487 |
| 490 for (auto operator_replacement : operator_replacement_pairs) { | 488 for (auto operator_replacement : operator_replacement_pairs) { |
| 491 uint32_t imm_operand = 17; | 489 uint32_t imm_operand = 17; |
| 492 BytecodeSourceInfo source_info(3, true); | 490 BytecodeNode first(Bytecode::kLdaSmi, imm_operand); |
| 493 BytecodeNode first(Bytecode::kLdaSmi, imm_operand, &source_info); | 491 first.source_info().Clone({3, true}); |
| 494 uint32_t reg_operand = Register(0).ToOperand(); | 492 uint32_t reg_operand = Register(0).ToOperand(); |
| 495 source_info.MakeStatementPosition(4); | 493 BytecodeNode second(operator_replacement[0], reg_operand, 1); |
| 496 BytecodeNode second(operator_replacement[0], reg_operand, 1, &source_info); | 494 second.source_info().Clone({4, true}); |
| 497 optimizer()->Write(&first); | 495 optimizer()->Write(&first); |
| 498 optimizer()->Write(&second); | 496 optimizer()->Write(&second); |
| 499 CHECK_EQ(last_written(), first); | 497 CHECK_EQ(last_written(), first); |
| 500 Flush(); | 498 Flush(); |
| 501 CHECK_EQ(last_written(), second); | 499 CHECK_EQ(last_written(), second); |
| 502 Reset(); | 500 Reset(); |
| 503 } | 501 } |
| 504 } | 502 } |
| 505 | 503 |
| 506 TEST_F(BytecodePeepholeOptimizerTest, MergeLdaZeroWithBinaryOp) { | 504 TEST_F(BytecodePeepholeOptimizerTest, MergeLdaZeroWithBinaryOp) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 526 CHECK_EQ(last_written().operand(0), 0); | 524 CHECK_EQ(last_written().operand(0), 0); |
| 527 CHECK_EQ(last_written().operand(1), reg_operand); | 525 CHECK_EQ(last_written().operand(1), reg_operand); |
| 528 CHECK_EQ(last_written().operand(2), idx_operand); | 526 CHECK_EQ(last_written().operand(2), idx_operand); |
| 529 Reset(); | 527 Reset(); |
| 530 } | 528 } |
| 531 } | 529 } |
| 532 | 530 |
| 533 } // namespace interpreter | 531 } // namespace interpreter |
| 534 } // namespace internal | 532 } // namespace internal |
| 535 } // namespace v8 | 533 } // namespace v8 |
| OLD | NEW |