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

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