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

Side by Side Diff: src/interpreter/register-translator.cc

Issue 1633153002: [interpreter] Reduce move operations for wide register support. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Remove RegisterOperandIsMovable from RegisterMover interface Created 4 years, 10 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
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/interpreter/register-translator.h" 5 #include "src/interpreter/register-translator.h"
6 6
7 #include "src/interpreter/bytecode-array-builder.h" 7 #include "src/interpreter/bytecode-array-builder.h"
8 8
9 namespace v8 { 9 namespace v8 {
10 namespace internal { 10 namespace internal {
11 namespace interpreter { 11 namespace interpreter {
12 12
13 RegisterTranslator::RegisterTranslator(RegisterMover* mover) 13 RegisterTranslator::RegisterTranslator(RegisterMover* mover)
14 : mover_(mover), emitting_moves_(false), window_registers_count_(0) {} 14 : mover_(mover),
15 emitting_moves_(false),
16 window_registers_count_(0),
17 output_moves_count_(0) {}
15 18
16 void RegisterTranslator::TranslateInputRegisters(Bytecode bytecode, 19 void RegisterTranslator::TranslateInputRegisters(Bytecode bytecode,
17 uint32_t* raw_operands, 20 uint32_t* raw_operands,
18 int raw_operand_count) { 21 int raw_operand_count) {
19 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), raw_operand_count); 22 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), raw_operand_count);
20 if (!emitting_moves_) { 23 if (!emitting_moves_) {
21 emitting_moves_ = true; 24 emitting_moves_ = true;
22 DCHECK_EQ(window_registers_count_, 0); 25 DCHECK_EQ(window_registers_count_, 0);
23 int register_bitmap = Bytecodes::GetRegisterOperandBitmap(bytecode); 26 int register_bitmap = Bytecodes::GetRegisterOperandBitmap(bytecode);
24 for (int i = 0; i < raw_operand_count; i++) { 27 for (int i = 0; i < raw_operand_count; i++) {
25 if ((register_bitmap & (1 << i)) == 0) { 28 if ((register_bitmap & (1 << i)) == 0) {
26 continue; 29 continue;
27 } 30 }
28 Register in_reg = Register::FromRawOperand(raw_operands[i]); 31 Register in_reg = Register::FromRawOperand(raw_operands[i]);
29 Register out_reg = TranslateAndMove(bytecode, i, in_reg); 32 Register out_reg = TranslateAndMove(bytecode, i, in_reg);
30 raw_operands[i] = out_reg.ToRawOperand(); 33 raw_operands[i] = out_reg.ToRawOperand();
31 } 34 }
35 window_registers_count_ = 0;
32 emitting_moves_ = false; 36 emitting_moves_ = false;
33 } else { 37 } else {
34 // When the register translator is translating registers, it will 38 // When the register translator is translating registers, it will
35 // cause the bytecode generator to emit moves on it's behalf. This 39 // cause the bytecode generator to emit moves on it's behalf. This
36 // path is reached by these moves. 40 // path is reached by these moves.
37 DCHECK(bytecode == Bytecode::kMovWide && raw_operand_count == 2 && 41 DCHECK(bytecode == Bytecode::kMovWide && raw_operand_count == 2 &&
38 Register::FromRawOperand(raw_operands[0]).is_valid() && 42 Register::FromRawOperand(raw_operands[0]).is_valid() &&
39 Register::FromRawOperand(raw_operands[1]).is_valid()); 43 Register::FromRawOperand(raw_operands[1]).is_valid());
40 } 44 }
41 } 45 }
42 46
43 Register RegisterTranslator::TranslateAndMove(Bytecode bytecode, 47 Register RegisterTranslator::TranslateAndMove(Bytecode bytecode,
44 int operand_index, Register reg) { 48 int operand_index, Register reg) {
49 if (FitsInReg8Operand(reg)) {
50 return reg;
51 }
52
45 OperandType operand_type = Bytecodes::GetOperandType(bytecode, operand_index); 53 OperandType operand_type = Bytecodes::GetOperandType(bytecode, operand_index);
54 OperandSize operand_size = Bytecodes::SizeOfOperand(operand_type);
55 if (operand_size == OperandSize::kShort) {
56 CHECK(FitsInReg16Operand(reg));
57 return Translate(reg);
58 }
59
60 CHECK((operand_type == OperandType::kReg8 ||
61 operand_type == OperandType::kRegOut8) &&
62 RegisterIsMovableToWindow(bytecode, operand_index));
46 Register translated_reg = Translate(reg); 63 Register translated_reg = Translate(reg);
47 Register addressable_reg = MakeAddressable(translated_reg, operand_type); 64 Register window_reg(kTranslationWindowStart + window_registers_count_);
48 if (addressable_reg != translated_reg) { 65 window_registers_count_ += 1;
49 CHECK(operand_type == OperandType::kReg8 && 66 if (Bytecodes::IsRegisterInputOperandType(operand_type)) {
50 mover()->RegisterOperandIsMovable(bytecode, operand_index)); 67 DCHECK(!Bytecodes::IsRegisterOutputOperandType(operand_type));
51 mover()->MoveRegisterUntranslated(translated_reg, addressable_reg); 68 mover()->MoveRegisterUntranslated(translated_reg, window_reg);
69 } else if (Bytecodes::IsRegisterOutputOperandType(operand_type)) {
70 DCHECK_LT(output_moves_count_, kTranslationWindowLength);
71 output_moves_[output_moves_count_] =
72 std::make_pair(window_reg, translated_reg);
73 output_moves_count_ += 1;
74 } else {
75 UNREACHABLE();
52 } 76 }
53 return addressable_reg; 77 return window_reg;
78 }
79
80 // static
81 bool RegisterTranslator::RegisterIsMovableToWindow(Bytecode bytecode,
82 int operand_index) {
83 // By design, we only support moving individual registers. There
84 // should be wide variants of such bytecodes instead to avoid the
85 // need for a large translation window.
86 OperandType operand_type = Bytecodes::GetOperandType(bytecode, operand_index);
87 if (operand_type != OperandType::kReg8 &&
88 operand_type != OperandType::kRegOut8) {
89 return false;
90 } else if (operand_index + 1 == Bytecodes::NumberOfOperands(bytecode)) {
91 return true;
92 } else {
93 OperandType next_operand_type =
94 Bytecodes::GetOperandType(bytecode, operand_index + 1);
95 return (next_operand_type != OperandType::kRegCount8 &&
96 next_operand_type != OperandType::kRegCount16);
97 }
54 } 98 }
55 99
56 void RegisterTranslator::TranslateOutputRegisters() { 100 void RegisterTranslator::TranslateOutputRegisters() {
57 if (!emitting_moves_) { 101 if (!emitting_moves_) {
58 emitting_moves_ = true; 102 emitting_moves_ = true;
59 while (window_registers_count_ > 0) { 103 while (output_moves_count_ > 0) {
60 window_registers_count_ -= 1; 104 output_moves_count_ -= 1;
61 Register source(kTranslationWindowStart + window_registers_count_); 105 mover()->MoveRegisterUntranslated(
62 Register destination = window_registers_[window_registers_count_]; 106 output_moves_[output_moves_count_].first,
63 mover()->MoveRegisterUntranslated(source, destination); 107 output_moves_[output_moves_count_].second);
64 } 108 }
65 emitting_moves_ = false; 109 emitting_moves_ = false;
66 } 110 }
67 } 111 }
68 112
69 Register RegisterTranslator::MakeAddressable(Register reg,
70 OperandType reg_type) {
71 DCHECK(!InTranslationWindow(reg));
72 OperandSize reg_size = Bytecodes::SizeOfOperand(reg_type);
73 if (reg_size == OperandSize::kByte && !FitsInReg8Operand(reg)) {
74 // TODO(oth): Moves into and out from translation window could be
75 // decoupled if there were metadata to say whether the register
76 // operand was an input, output, or input-and-output for a given
77 // bytecode.
78 Register destination(kTranslationWindowStart + window_registers_count_);
79 window_registers_[window_registers_count_] = reg;
80 window_registers_count_ += 1;
81 DCHECK_LE(window_registers_count_, kTranslationWindowLength);
82 return destination;
83 } else {
84 return reg;
85 }
86 }
87
88 // static 113 // static
89 Register RegisterTranslator::Translate(Register reg) { 114 Register RegisterTranslator::Translate(Register reg) {
90 if (reg.index() >= kTranslationWindowStart) { 115 if (reg.index() >= kTranslationWindowStart) {
91 return Register(reg.index() + kTranslationWindowLength); 116 return Register(reg.index() + kTranslationWindowLength);
92 } else { 117 } else {
93 return reg; 118 return reg;
94 } 119 }
95 } 120 }
96 121
97 // static 122 // static
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 // relocate window to limit waste. 164 // relocate window to limit waste.
140 return kTranslationWindowLimit + 1 - register_count; 165 return kTranslationWindowLimit + 1 - register_count;
141 } 166 }
142 } 167 }
143 return 0; 168 return 0;
144 } 169 }
145 170
146 } // namespace interpreter 171 } // namespace interpreter
147 } // namespace internal 172 } // namespace internal
148 } // namespace v8 173 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/register-translator.h ('k') | test/cctest/interpreter/test-bytecode-generator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698