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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/int64-lowering.h ('k') | src/compiler/wasm-compiler.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/int64-lowering.cc
diff --git a/src/compiler/int64-lowering.cc b/src/compiler/int64-lowering.cc
index c2952319be24a4345a4095bb6a2e221f6b7a9edf..c9c87b65d6de55807e5fa6a13afbe5bc232a3287 100644
--- a/src/compiler/int64-lowering.cc
+++ b/src/compiler/int64-lowering.cc
@@ -5,8 +5,12 @@
#include "src/compiler/int64-lowering.h"
#include "src/compiler/common-operator.h"
#include "src/compiler/graph.h"
+#include "src/compiler/linkage.h"
#include "src/compiler/machine-operator.h"
+#include "src/compiler/node-properties.h"
+
#include "src/compiler/node.h"
+#include "src/wasm/wasm-module.h"
#include "src/zone.h"
namespace v8 {
@@ -14,17 +18,23 @@ namespace internal {
namespace compiler {
Int64Lowering::Int64Lowering(Graph* graph, MachineOperatorBuilder* machine,
- CommonOperatorBuilder* common, Zone* zone)
- : graph_(graph),
+ CommonOperatorBuilder* common, Zone* zone,
+ Signature<MachineRepresentation>* signature)
+ : zone_(zone),
+ graph_(graph),
machine_(machine),
common_(common),
state_(graph, 4),
stack_(zone),
- replacements_(zone->NewArray<Replacement>(graph->NodeCount())) {
+ replacements_(zone->NewArray<Replacement>(graph->NodeCount())),
+ signature_(signature) {
memset(replacements_, 0, sizeof(Replacement) * graph->NodeCount());
}
-void Int64Lowering::ReduceGraph() {
+void Int64Lowering::LowerGraph() {
+ if (4 != kPointerSize) {
+ return;
+ }
stack_.push(graph()->end());
state_.Set(graph()->end(), State::kOnStack);
@@ -34,7 +44,7 @@ void Int64Lowering::ReduceGraph() {
stack_.pop();
state_.Set(top, State::kVisited);
// All inputs of top have already been reduced, now reduce top.
- ReduceNode(top);
+ LowerNode(top);
} else {
// Push all children onto the stack.
for (Node* input : top->inputs()) {
@@ -48,7 +58,35 @@ void Int64Lowering::ReduceGraph() {
}
}
-void Int64Lowering::ReduceNode(Node* node) {
+static int GetParameterIndexAfterLowering(
+ Signature<MachineRepresentation>* signature, int old_index) {
+ int result = old_index;
+ for (int i = 0; i < old_index; i++) {
+ if (signature->GetParam(i) == MachineRepresentation::kWord64) {
+ result++;
+ }
+ }
+ return result;
+}
+
+static int GetParameterCountAfterLowering(
+ Signature<MachineRepresentation>* signature) {
+ return GetParameterIndexAfterLowering(
+ signature, static_cast<int>(signature->parameter_count()));
+}
+
+static int GetReturnCountAfterLowering(
+ Signature<MachineRepresentation>* signature) {
+ int result = static_cast<int>(signature->return_count());
+ for (int i = 0; i < static_cast<int>(signature->return_count()); i++) {
+ if (signature->GetReturn(i) == MachineRepresentation::kWord64) {
+ result++;
+ }
+ }
+ return result;
+}
+
+void Int64Lowering::LowerNode(Node* node) {
switch (node->opcode()) {
case IrOpcode::kInt64Constant: {
int64_t value = OpParameter<int64_t>(node);
@@ -56,48 +94,207 @@ void Int64Lowering::ReduceNode(Node* node) {
common()->Int32Constant(static_cast<int32_t>(value & 0xFFFFFFFF)));
Node* high_node = graph()->NewNode(
common()->Int32Constant(static_cast<int32_t>(value >> 32)));
- replacements_[node->id()].low = low_node;
- replacements_[node->id()].high = high_node;
+ ReplaceNode(node, low_node, high_node);
+ break;
+ }
+ case IrOpcode::kLoad: {
+ LoadRepresentation load_rep = LoadRepresentationOf(node->op());
+
+ if (load_rep.representation() == MachineRepresentation::kWord64) {
+ Node* base = node->InputAt(0);
+ Node* index = node->InputAt(1);
+ Node* index_high =
+ graph()->NewNode(machine()->Int32Add(), index,
+ graph()->NewNode(common()->Int32Constant(4)));
+
+ const Operator* load_op = machine()->Load(MachineType::Int32());
+ Node* high_node;
+ if (node->InputCount() > 2) {
+ Node* effect_high = node->InputAt(2);
+ Node* control_high = node->InputAt(3);
+ high_node = graph()->NewNode(load_op, base, index_high, effect_high,
+ control_high);
+ // change the effect change from old_node --> old_effect to
+ // old_node --> high_node --> old_effect.
+ node->ReplaceInput(2, high_node);
+ } else {
+ high_node = graph()->NewNode(load_op, base, index_high);
+ }
+ NodeProperties::ChangeOp(node, load_op);
+ ReplaceNode(node, node, high_node);
+ }
+ break;
+ }
+ case IrOpcode::kStore: {
+ StoreRepresentation store_rep = StoreRepresentationOf(node->op());
+ if (store_rep.representation() == MachineRepresentation::kWord64) {
+ // We change the original store node to store the low word, and create
+ // a new store node to store the high word. The effect and control edges
+ // are copied from the original store to the new store node, the effect
+ // edge of the original store is redirected to the new store.
+ WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind();
+
+ Node* base = node->InputAt(0);
+ Node* index = node->InputAt(1);
+ Node* index_high =
+ graph()->NewNode(machine()->Int32Add(), index,
+ graph()->NewNode(common()->Int32Constant(4)));
+
+ Node* value = node->InputAt(2);
+ DCHECK(HasReplacementLow(value));
+ DCHECK(HasReplacementHigh(value));
+
+ const Operator* store_op = machine()->Store(StoreRepresentation(
+ MachineRepresentation::kWord32, write_barrier_kind));
+
+ Node* high_node;
+ if (node->InputCount() > 3) {
+ Node* effect_high = node->InputAt(3);
+ Node* control_high = node->InputAt(4);
+ high_node = graph()->NewNode(store_op, base, index_high,
+ GetReplacementHigh(value), effect_high,
+ control_high);
+ node->ReplaceInput(3, high_node);
+
+ } else {
+ high_node = graph()->NewNode(store_op, base, index_high,
+ GetReplacementHigh(value));
+ }
+
+ node->ReplaceInput(2, GetReplacementLow(value));
+ NodeProperties::ChangeOp(node, store_op);
+ ReplaceNode(node, node, high_node);
+ }
break;
}
case IrOpcode::kWord64And: {
+ DCHECK(node->InputCount() == 2);
Node* left = node->InputAt(0);
- DCHECK(replacements_[left->id()].low);
- Node* left_low = replacements_[left->id()].low;
- Node* left_high = replacements_[left->id()].high;
-
Node* right = node->InputAt(1);
- DCHECK(replacements_[right->id()].low);
- Node* right_low = replacements_[right->id()].low;
- Node* right_high = replacements_[right->id()].high;
-
- replacements_[node->id()].low =
- graph()->NewNode(machine()->Word32And(), left_low, right_low);
- replacements_[node->id()].high =
- graph()->NewNode(machine()->Word32And(), left_high, right_high);
+
+ Node* low_node =
+ graph()->NewNode(machine()->Word32And(), GetReplacementLow(left),
+ GetReplacementLow(right));
+ Node* high_node =
+ graph()->NewNode(machine()->Word32And(), GetReplacementHigh(left),
+ GetReplacementHigh(right));
+ ReplaceNode(node, low_node, high_node);
break;
}
case IrOpcode::kTruncateInt64ToInt32: {
+ DCHECK(node->InputCount() == 1);
Node* input = node->InputAt(0);
- DCHECK(replacements_[input->id()].low);
- replacements_[node->id()].low = replacements_[input->id()].low;
+ ReplaceNode(node, GetReplacementLow(input), nullptr);
+ node->NullAllInputs();
break;
}
- default: {
- // Also the inputs of nodes can change which do not expect int64 inputs.
- for (int i = 0; i < node->InputCount(); i++) {
- Node* input = node->InputAt(i);
- // The input has changed altough it was not an int64 input. This can
- // happen e.g. if the input node is IrOpcode::kTruncateInt64ToInt32. We
- // use the low word replacement as the new input.
- if (replacements_[input->id()].low) {
- node->ReplaceInput(i, replacements_[input->id()].low);
+ case IrOpcode::kStart: {
+ int parameter_count = GetParameterCountAfterLowering(signature());
+ // Only exchange the node if the parameter count actually changed.
+ if (parameter_count != signature()->parameter_count()) {
+ int delta =
+ parameter_count - static_cast<int>(signature()->parameter_count());
+ int new_output_count = node->op()->ValueOutputCount() + delta;
+ NodeProperties::ChangeOp(node, common()->Start(new_output_count));
+ }
+ break;
+ }
+ case IrOpcode::kParameter: {
+ DCHECK(node->InputCount() == 1);
+ // Only exchange the node if the parameter count actually changed. We do
+ // not even have to do the default lowering because the the start node,
+ // the only input of a parameter node, only changes if the parameter count
+ // changes.
+ if (GetParameterCountAfterLowering(signature()) !=
+ signature()->parameter_count()) {
+ int old_index = ParameterIndexOf(node->op());
+ int new_index = GetParameterIndexAfterLowering(signature(), old_index);
+ Node* low_node =
+ graph()->NewNode(common()->Parameter(new_index), graph()->start());
+
+ Node* high_node = nullptr;
+ if (signature()->GetParam(old_index) ==
+ MachineRepresentation::kWord64) {
+ high_node = graph()->NewNode(common()->Parameter(new_index + 1),
+ graph()->start());
}
+ ReplaceNode(node, low_node, high_node);
+ }
+ break;
+ }
+ case IrOpcode::kReturn: {
+ DefaultLowering(node);
+ int new_return_count = GetReturnCountAfterLowering(signature());
+ if (signature()->return_count() != new_return_count) {
+ NodeProperties::ChangeOp(node, common()->Return(new_return_count));
}
+ break;
+ }
+ case IrOpcode::kCall: {
+ CallDescriptor* descriptor = OpParameter<CallDescriptor*>(node);
+ if (DefaultLowering(node) ||
+ (descriptor->ReturnCount() == 1 &&
+ descriptor->GetReturnType(0) == MachineType::Int64())) {
+ // We have to adjust the call descriptor.
+ const Operator* op = common()->Call(
+ wasm::ModuleEnv::GetI32WasmCallDescriptor(zone(), descriptor));
+ NodeProperties::ChangeOp(node, op);
+ }
+ if (descriptor->ReturnCount() == 1 &&
+ descriptor->GetReturnType(0) == MachineType::Int64()) {
+ // We access the additional return values through projections.
+ Node* low_node = graph()->NewNode(common()->Projection(0), node);
+ Node* high_node = graph()->NewNode(common()->Projection(1), node);
+ ReplaceNode(node, low_node, high_node);
+ }
+ break;
}
+ default: { DefaultLowering(node); }
}
}
+bool Int64Lowering::DefaultLowering(Node* node) {
+ bool something_changed = false;
+ for (int i = NodeProperties::PastValueIndex(node) - 1; i >= 0; i--) {
+ Node* input = node->InputAt(i);
+ if (HasReplacementLow(input)) {
+ something_changed = true;
+ node->ReplaceInput(i, GetReplacementLow(input));
+ }
+ if (HasReplacementHigh(input)) {
+ something_changed = true;
+ node->InsertInput(zone(), i + 1, GetReplacementHigh(input));
+ }
+ }
+ return something_changed;
+}
+
+void Int64Lowering::ReplaceNode(Node* old, Node* new_low, Node* new_high) {
+ // if new_low == nullptr, then also new_high == nullptr.
+ DCHECK(new_low != nullptr || new_high == nullptr);
+ replacements_[old->id()].low = new_low;
+ replacements_[old->id()].high = new_high;
+}
+
+bool Int64Lowering::HasReplacementLow(Node* node) {
+ return replacements_[node->id()].low != nullptr;
+}
+
+Node* Int64Lowering::GetReplacementLow(Node* node) {
+ Node* result = replacements_[node->id()].low;
+ DCHECK(result);
+ return result;
+}
+
+bool Int64Lowering::HasReplacementHigh(Node* node) {
+ return replacements_[node->id()].high != nullptr;
+}
+
+Node* Int64Lowering::GetReplacementHigh(Node* node) {
+ Node* result = replacements_[node->id()].high;
+ DCHECK(result);
+ return result;
+}
} // namespace compiler
} // namespace internal
} // namespace v8
« 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