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

Side by Side Diff: src/compiler/int64-lowering.cc

Issue 1704033002: [wasm] WasmRunner can run tests with I64 parameters and return value. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@new_wasm_runner
Patch Set: Review Comments. 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
« no previous file with comments | « src/compiler/int64-lowering.h ('k') | src/compiler/wasm-compiler.cc » ('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 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 "src/compiler/int64-lowering.h" 5 #include "src/compiler/int64-lowering.h"
6 #include "src/compiler/common-operator.h" 6 #include "src/compiler/common-operator.h"
7 #include "src/compiler/graph.h" 7 #include "src/compiler/graph.h"
8 #include "src/compiler/linkage.h"
8 #include "src/compiler/machine-operator.h" 9 #include "src/compiler/machine-operator.h"
10 #include "src/compiler/node-properties.h"
11
9 #include "src/compiler/node.h" 12 #include "src/compiler/node.h"
13 #include "src/wasm/wasm-module.h"
10 #include "src/zone.h" 14 #include "src/zone.h"
11 15
12 namespace v8 { 16 namespace v8 {
13 namespace internal { 17 namespace internal {
14 namespace compiler { 18 namespace compiler {
15 19
16 Int64Lowering::Int64Lowering(Graph* graph, MachineOperatorBuilder* machine, 20 Int64Lowering::Int64Lowering(Graph* graph, MachineOperatorBuilder* machine,
17 CommonOperatorBuilder* common, Zone* zone) 21 CommonOperatorBuilder* common, Zone* zone,
18 : graph_(graph), 22 Signature<MachineRepresentation>* signature)
23 : zone_(zone),
24 graph_(graph),
19 machine_(machine), 25 machine_(machine),
20 common_(common), 26 common_(common),
21 state_(graph, 4), 27 state_(graph, 4),
22 stack_(zone), 28 stack_(zone),
23 replacements_(zone->NewArray<Replacement>(graph->NodeCount())) { 29 replacements_(zone->NewArray<Replacement>(graph->NodeCount())),
30 signature_(signature) {
24 memset(replacements_, 0, sizeof(Replacement) * graph->NodeCount()); 31 memset(replacements_, 0, sizeof(Replacement) * graph->NodeCount());
25 } 32 }
26 33
27 void Int64Lowering::ReduceGraph() { 34 void Int64Lowering::LowerGraph() {
35 DCHECK_EQ(4, kPointerSize);
titzer 2016/02/18 13:38:31 Please don't assert that. We'll want to write unit
28 stack_.push(graph()->end()); 36 stack_.push(graph()->end());
29 state_.Set(graph()->end(), State::kOnStack); 37 state_.Set(graph()->end(), State::kOnStack);
30 38
31 while (!stack_.empty()) { 39 while (!stack_.empty()) {
32 Node* top = stack_.top(); 40 Node* top = stack_.top();
33 if (state_.Get(top) == State::kInputsPushed) { 41 if (state_.Get(top) == State::kInputsPushed) {
34 stack_.pop(); 42 stack_.pop();
35 state_.Set(top, State::kVisited); 43 state_.Set(top, State::kVisited);
36 // All inputs of top have already been reduced, now reduce top. 44 // All inputs of top have already been reduced, now reduce top.
37 ReduceNode(top); 45 LowerNode(top);
38 } else { 46 } else {
39 // Push all children onto the stack. 47 // Push all children onto the stack.
40 for (Node* input : top->inputs()) { 48 for (Node* input : top->inputs()) {
41 if (state_.Get(input) == State::kUnvisited) { 49 if (state_.Get(input) == State::kUnvisited) {
42 stack_.push(input); 50 stack_.push(input);
43 state_.Set(input, State::kOnStack); 51 state_.Set(input, State::kOnStack);
44 } 52 }
45 } 53 }
46 state_.Set(top, State::kInputsPushed); 54 state_.Set(top, State::kInputsPushed);
47 } 55 }
48 } 56 }
49 } 57 }
50 58
51 void Int64Lowering::ReduceNode(Node* node) { 59 static int GetParameterIndexAfterLowering(
60 Signature<MachineRepresentation>* signature, int old_index) {
61 int result = old_index;
62 for (int i = 0; i < old_index; i++) {
63 if (signature->GetParam(i) == MachineRepresentation::kWord64) {
64 result++;
65 }
66 }
67 return result;
68 }
69
70 static int GetParameterCountAfterLowering(
71 Signature<MachineRepresentation>* signature) {
72 return GetParameterIndexAfterLowering(
73 signature, static_cast<int>(signature->parameter_count()));
74 }
75
76 static int GetReturnCountAfterLowering(
77 Signature<MachineRepresentation>* signature) {
78 int result = static_cast<int>(signature->return_count());
79 for (int i = 0; i < static_cast<int>(signature->return_count()); i++) {
80 if (signature->GetReturn(i) == MachineRepresentation::kWord64) {
81 result++;
82 }
83 }
84 return result;
85 }
86
87 void Int64Lowering::LowerNode(Node* node) {
52 switch (node->opcode()) { 88 switch (node->opcode()) {
53 case IrOpcode::kInt64Constant: { 89 case IrOpcode::kInt64Constant: {
54 int64_t value = OpParameter<int64_t>(node); 90 int64_t value = OpParameter<int64_t>(node);
55 Node* low_node = graph()->NewNode( 91 Node* low_node = graph()->NewNode(
56 common()->Int32Constant(static_cast<int32_t>(value & 0xFFFFFFFF))); 92 common()->Int32Constant(static_cast<int32_t>(value & 0xFFFFFFFF)));
57 Node* high_node = graph()->NewNode( 93 Node* high_node = graph()->NewNode(
58 common()->Int32Constant(static_cast<int32_t>(value >> 32))); 94 common()->Int32Constant(static_cast<int32_t>(value >> 32)));
59 replacements_[node->id()].low = low_node; 95 ReplaceNode(node, low_node, high_node);
60 replacements_[node->id()].high = high_node; 96 break;
97 }
98 case IrOpcode::kLoad: {
99 LoadRepresentation load_rep = LoadRepresentationOf(node->op());
100
101 if (load_rep.representation() == MachineRepresentation::kWord64) {
102 Node* base = node->InputAt(0);
103 Node* index = node->InputAt(1);
104 Node* index_high =
105 graph()->NewNode(machine()->Int32Add(), index,
106 graph()->NewNode(common()->Int32Constant(4)));
107
108 const Operator* load_op = machine()->Load(MachineType::Int32());
109 Node* high_node;
110 if (node->InputCount() > 2) {
111 Node* effect_high = node->InputAt(2);
112 Node* control_high = node->InputAt(3);
113 high_node = graph()->NewNode(load_op, base, index_high, effect_high,
114 control_high);
115 // change the effect change from old_node --> old_effect to
116 // old_node --> high_node --> old_effect.
117 node->ReplaceInput(2, high_node);
118 } else {
119 high_node = graph()->NewNode(load_op, base, index_high);
120 }
121 NodeProperties::ChangeOp(node, load_op);
122 ReplaceNode(node, node, high_node);
123 }
124 break;
125 }
126 case IrOpcode::kStore: {
127 StoreRepresentation store_rep = StoreRepresentationOf(node->op());
128 if (store_rep.representation() == MachineRepresentation::kWord64) {
129 // We change the original store node to store the low word, and create
130 // a new store node to store the high word. The effect and control edges
131 // are copied from the original store to the new store node, the effect
132 // edge of the original store is redirected to the new store.
133 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind();
134
135 Node* base = node->InputAt(0);
136 Node* index = node->InputAt(1);
137 Node* index_high =
138 graph()->NewNode(machine()->Int32Add(), index,
139 graph()->NewNode(common()->Int32Constant(4)));
140
141 Node* value = node->InputAt(2);
142 DCHECK(HasReplacementLow(value));
143 DCHECK(HasReplacementHigh(value));
144
145 const Operator* store_op = machine()->Store(StoreRepresentation(
146 MachineRepresentation::kWord32, write_barrier_kind));
147
148 Node* high_node;
149 if (node->InputCount() > 3) {
150 Node* effect_high = node->InputAt(3);
151 Node* control_high = node->InputAt(4);
152 high_node = graph()->NewNode(store_op, base, index_high,
153 GetReplacementHigh(value), effect_high,
154 control_high);
155 node->ReplaceInput(3, high_node);
156
157 } else {
158 high_node = graph()->NewNode(store_op, base, index_high,
159 GetReplacementHigh(value));
160 }
161
162 node->ReplaceInput(2, GetReplacementLow(value));
163 NodeProperties::ChangeOp(node, store_op);
164 ReplaceNode(node, node, high_node);
165 }
61 break; 166 break;
62 } 167 }
63 case IrOpcode::kWord64And: { 168 case IrOpcode::kWord64And: {
169 DCHECK(node->InputCount() == 2);
64 Node* left = node->InputAt(0); 170 Node* left = node->InputAt(0);
65 DCHECK(replacements_[left->id()].low);
66 Node* left_low = replacements_[left->id()].low;
67 Node* left_high = replacements_[left->id()].high;
68
69 Node* right = node->InputAt(1); 171 Node* right = node->InputAt(1);
70 DCHECK(replacements_[right->id()].low); 172
71 Node* right_low = replacements_[right->id()].low; 173 Node* low_node =
72 Node* right_high = replacements_[right->id()].high; 174 graph()->NewNode(machine()->Word32And(), GetReplacementLow(left),
73 175 GetReplacementLow(right));
74 replacements_[node->id()].low = 176 Node* high_node =
75 graph()->NewNode(machine()->Word32And(), left_low, right_low); 177 graph()->NewNode(machine()->Word32And(), GetReplacementHigh(left),
76 replacements_[node->id()].high = 178 GetReplacementHigh(right));
77 graph()->NewNode(machine()->Word32And(), left_high, right_high); 179 ReplaceNode(node, low_node, high_node);
78 break; 180 break;
79 } 181 }
80 case IrOpcode::kTruncateInt64ToInt32: { 182 case IrOpcode::kTruncateInt64ToInt32: {
183 DCHECK(node->InputCount() == 1);
81 Node* input = node->InputAt(0); 184 Node* input = node->InputAt(0);
82 DCHECK(replacements_[input->id()].low); 185 ReplaceNode(node, GetReplacementLow(input), nullptr);
83 replacements_[node->id()].low = replacements_[input->id()].low; 186 node->NullAllInputs();
84 break; 187 break;
85 } 188 }
86 default: { 189 case IrOpcode::kStart: {
87 // Also the inputs of nodes can change which do not expect int64 inputs. 190 int parameter_count = GetParameterCountAfterLowering(signature());
88 for (int i = 0; i < node->InputCount(); i++) { 191 // Only exchange the node if the parameter count actually changed.
89 Node* input = node->InputAt(i); 192 if (parameter_count != signature()->parameter_count()) {
90 // The input has changed altough it was not an int64 input. This can 193 int delta =
91 // happen e.g. if the input node is IrOpcode::kTruncateInt64ToInt32. We 194 parameter_count - static_cast<int>(signature()->parameter_count());
92 // use the low word replacement as the new input. 195 int new_output_count = node->op()->ValueOutputCount() + delta;
93 if (replacements_[input->id()].low) { 196 NodeProperties::ChangeOp(node, common()->Start(new_output_count));
94 node->ReplaceInput(i, replacements_[input->id()].low); 197 }
198 break;
199 }
200 case IrOpcode::kParameter: {
201 DCHECK(node->InputCount() == 1);
202 // Only exchange the node if the parameter count actually changed. We do
203 // not even have to do the default lowering because the the start node,
204 // the only input of a parameter node, only changes if the parameter count
205 // changes.
206 if (GetParameterCountAfterLowering(signature()) !=
207 signature()->parameter_count()) {
208 int old_index = ParameterIndexOf(node->op());
209 int new_index = GetParameterIndexAfterLowering(signature(), old_index);
210 Node* low_node =
211 graph()->NewNode(common()->Parameter(new_index), graph()->start());
212
213 Node* high_node = nullptr;
214 if (signature()->GetParam(old_index) ==
215 MachineRepresentation::kWord64) {
216 high_node = graph()->NewNode(common()->Parameter(new_index + 1),
217 graph()->start());
95 } 218 }
96 } 219 ReplaceNode(node, low_node, high_node);
97 } 220 }
221 break;
222 }
223 case IrOpcode::kReturn: {
224 DefaultLowering(node);
225 int new_return_count = GetReturnCountAfterLowering(signature());
226 if (signature()->return_count() != new_return_count) {
227 NodeProperties::ChangeOp(node, common()->Return(new_return_count));
228 }
229 break;
230 }
231 case IrOpcode::kCall: {
232 CallDescriptor* descriptor = OpParameter<CallDescriptor*>(node);
233 if (DefaultLowering(node) ||
234 (descriptor->ReturnCount() == 1 &&
235 descriptor->GetReturnType(0) == MachineType::Int64())) {
236 // We have to adjust the call descriptor.
237 const Operator* op = common()->Call(
238 wasm::ModuleEnv::GetI32WasmCallDescriptor(zone(), descriptor));
239 NodeProperties::ChangeOp(node, op);
240 }
241 if (descriptor->ReturnCount() == 1 &&
242 descriptor->GetReturnType(0) == MachineType::Int64()) {
243 // We access the additional return values through projections.
244 Node* low_node = graph()->NewNode(common()->Projection(0), node);
245 Node* high_node = graph()->NewNode(common()->Projection(1), node);
246 ReplaceNode(node, low_node, high_node);
247 }
248 break;
249 }
250 default: { DefaultLowering(node); }
98 } 251 }
99 } 252 }
100 253
254 bool Int64Lowering::DefaultLowering(Node* node) {
255 bool something_changed = false;
256 for (int i = NodeProperties::PastValueIndex(node) - 1; i >= 0; i--) {
257 Node* input = node->InputAt(i);
258 if (HasReplacementLow(input)) {
259 something_changed = true;
260 node->ReplaceInput(i, GetReplacementLow(input));
261 }
262 if (HasReplacementHigh(input)) {
263 something_changed = true;
264 node->InsertInput(zone(), i + 1, GetReplacementHigh(input));
265 }
266 }
267 return something_changed;
268 }
269
270 void Int64Lowering::ReplaceNode(Node* old, Node* new_low, Node* new_high) {
271 // if new_low == nullptr, then also new_high == nullptr.
272 DCHECK(new_low != nullptr || new_high == nullptr);
273 replacements_[old->id()].low = new_low;
274 replacements_[old->id()].high = new_high;
275 }
276
277 bool Int64Lowering::HasReplacementLow(Node* node) {
278 return replacements_[node->id()].low != nullptr;
279 }
280
281 Node* Int64Lowering::GetReplacementLow(Node* node) {
282 Node* result = replacements_[node->id()].low;
283 DCHECK(result);
284 return result;
285 }
286
287 bool Int64Lowering::HasReplacementHigh(Node* node) {
288 return replacements_[node->id()].high != nullptr;
289 }
290
291 Node* Int64Lowering::GetReplacementHigh(Node* node) {
292 Node* result = replacements_[node->id()].high;
293 DCHECK(result);
294 return result;
295 }
101 } // namespace compiler 296 } // namespace compiler
102 } // namespace internal 297 } // namespace internal
103 } // namespace v8 298 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/int64-lowering.h ('k') | src/compiler/wasm-compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698