diff options
Diffstat (limited to 'deps/v8/src/compiler/int64-lowering.cc')
-rw-r--r-- | deps/v8/src/compiler/int64-lowering.cc | 198 |
1 files changed, 127 insertions, 71 deletions
diff --git a/deps/v8/src/compiler/int64-lowering.cc b/deps/v8/src/compiler/int64-lowering.cc index 8824a03dc9..737947aad0 100644 --- a/deps/v8/src/compiler/int64-lowering.cc +++ b/deps/v8/src/compiler/int64-lowering.cc @@ -32,6 +32,8 @@ Int64Lowering::Int64Lowering(Graph* graph, MachineOperatorBuilder* machine, signature_(signature), placeholder_(graph->NewNode(common->Parameter(-2, "placeholder"), graph->start())) { + DCHECK_NOT_NULL(graph); + DCHECK_NOT_NULL(graph->end()); replacements_ = zone->NewArray<Replacement>(graph->NodeCount()); memset(replacements_, 0, sizeof(Replacement) * graph->NodeCount()); } @@ -79,8 +81,10 @@ static int GetParameterIndexAfterLowering( return result; } -static int GetParameterCountAfterLowering( +int Int64Lowering::GetParameterCountAfterLowering( Signature<MachineRepresentation>* signature) { + // GetParameterIndexAfterLowering(parameter_count) returns the parameter count + // after lowering. return GetParameterIndexAfterLowering( signature, static_cast<int>(signature->parameter_count())); } @@ -96,6 +100,27 @@ static int GetReturnCountAfterLowering( return result; } +void Int64Lowering::GetIndexNodes(Node* index, Node*& index_low, + Node*& index_high) { +#if defined(V8_TARGET_LITTLE_ENDIAN) + index_low = index; + index_high = graph()->NewNode(machine()->Int32Add(), index, + graph()->NewNode(common()->Int32Constant(4))); +#elif defined(V8_TARGET_BIG_ENDIAN) + index_low = graph()->NewNode(machine()->Int32Add(), index, + graph()->NewNode(common()->Int32Constant(4))); + index_high = index; +#endif +} + +#if defined(V8_TARGET_LITTLE_ENDIAN) +const int Int64Lowering::kLowerWordOffset = 0; +const int Int64Lowering::kHigherWordOffset = 4; +#elif defined(V8_TARGET_BIG_ENDIAN) +const int Int64Lowering::kLowerWordOffset = 4; +const int Int64Lowering::kHigherWordOffset = 0; +#endif + void Int64Lowering::LowerNode(Node* node) { switch (node->opcode()) { case IrOpcode::kInt64Constant: { @@ -107,17 +132,31 @@ void Int64Lowering::LowerNode(Node* node) { ReplaceNode(node, low_node, high_node); break; } - case IrOpcode::kLoad: { - LoadRepresentation load_rep = LoadRepresentationOf(node->op()); + case IrOpcode::kLoad: + case IrOpcode::kUnalignedLoad: { + MachineRepresentation rep; + if (node->opcode() == IrOpcode::kLoad) { + rep = LoadRepresentationOf(node->op()).representation(); + } else { + DCHECK(node->opcode() == IrOpcode::kUnalignedLoad); + rep = UnalignedLoadRepresentationOf(node->op()).representation(); + } - if (load_rep.representation() == MachineRepresentation::kWord64) { + if (rep == 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))); + Node* index_low; + Node* index_high; + GetIndexNodes(index, index_low, index_high); + const Operator* load_op; + + if (node->opcode() == IrOpcode::kLoad) { + load_op = machine()->Load(MachineType::Int32()); + } else { + DCHECK(node->opcode() == IrOpcode::kUnalignedLoad); + load_op = machine()->UnalignedLoad(MachineType::Int32()); + } - const Operator* load_op = machine()->Load(MachineType::Int32()); Node* high_node; if (node->InputCount() > 2) { Node* effect_high = node->InputAt(2); @@ -130,6 +169,7 @@ void Int64Lowering::LowerNode(Node* node) { } else { high_node = graph()->NewNode(load_op, base, index_high); } + node->ReplaceInput(1, index_low); NodeProperties::ChangeOp(node, load_op); ReplaceNode(node, node, high_node); } else { @@ -137,27 +177,40 @@ void Int64Lowering::LowerNode(Node* node) { } break; } - case IrOpcode::kStore: { - StoreRepresentation store_rep = StoreRepresentationOf(node->op()); - if (store_rep.representation() == MachineRepresentation::kWord64) { + case IrOpcode::kStore: + case IrOpcode::kUnalignedStore: { + MachineRepresentation rep; + if (node->opcode() == IrOpcode::kStore) { + rep = StoreRepresentationOf(node->op()).representation(); + } else { + DCHECK(node->opcode() == IrOpcode::kUnalignedStore); + rep = UnalignedStoreRepresentationOf(node->op()); + } + + if (rep == 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* index_low; + Node* index_high; + GetIndexNodes(index, index_low, index_high); Node* value = node->InputAt(2); DCHECK(HasReplacementLow(value)); DCHECK(HasReplacementHigh(value)); - const Operator* store_op = machine()->Store(StoreRepresentation( - MachineRepresentation::kWord32, write_barrier_kind)); + const Operator* store_op; + if (node->opcode() == IrOpcode::kStore) { + WriteBarrierKind write_barrier_kind = + StoreRepresentationOf(node->op()).write_barrier_kind(); + store_op = machine()->Store(StoreRepresentation( + MachineRepresentation::kWord32, write_barrier_kind)); + } else { + DCHECK(node->opcode() == IrOpcode::kUnalignedStore); + store_op = machine()->UnalignedStore(MachineRepresentation::kWord32); + } Node* high_node; if (node->InputCount() > 3) { @@ -173,11 +226,14 @@ void Int64Lowering::LowerNode(Node* node) { GetReplacementHigh(value)); } + node->ReplaceInput(1, index_low); node->ReplaceInput(2, GetReplacementLow(value)); NodeProperties::ChangeOp(node, store_op); ReplaceNode(node, node, high_node); } else { - DefaultLowering(node); + if (HasReplacementLow(node->InputAt(2))) { + node->ReplaceInput(2, GetReplacementLow(node->InputAt(2))); + } } break; } @@ -223,7 +279,9 @@ void Int64Lowering::LowerNode(Node* node) { break; } case IrOpcode::kCall: { - CallDescriptor* descriptor = OpParameter<CallDescriptor*>(node); + // TODO(turbofan): Make WASM code const-correct wrt. CallDescriptor. + CallDescriptor* descriptor = + const_cast<CallDescriptor*>(CallDescriptorOf(node->op())); if (DefaultLowering(node) || (descriptor->ReturnCount() == 1 && descriptor->GetReturnType(0) == MachineType::Int64())) { @@ -235,8 +293,10 @@ void Int64Lowering::LowerNode(Node* node) { 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); + Node* low_node = + graph()->NewNode(common()->Projection(0), node, graph()->start()); + Node* high_node = + graph()->NewNode(common()->Projection(1), node, graph()->start()); ReplaceNode(node, low_node, high_node); } break; @@ -262,9 +322,6 @@ void Int64Lowering::LowerNode(Node* node) { node->NullAllInputs(); break; } - // todo(ahaas): I added a list of missing instructions here to make merging - // easier when I do them one by one. - // kExprI64Add: case IrOpcode::kInt64Add: { DCHECK(node->InputCount() == 2); @@ -278,13 +335,13 @@ void Int64Lowering::LowerNode(Node* node) { NodeProperties::ChangeOp(node, machine()->Int32PairAdd()); // 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); + Node* low_node = + graph()->NewNode(common()->Projection(0), node, graph()->start()); + Node* high_node = + graph()->NewNode(common()->Projection(1), node, graph()->start()); ReplaceNode(node, low_node, high_node); break; } - - // kExprI64Sub: case IrOpcode::kInt64Sub: { DCHECK(node->InputCount() == 2); @@ -298,12 +355,13 @@ void Int64Lowering::LowerNode(Node* node) { NodeProperties::ChangeOp(node, machine()->Int32PairSub()); // 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); + Node* low_node = + graph()->NewNode(common()->Projection(0), node, graph()->start()); + Node* high_node = + graph()->NewNode(common()->Projection(1), node, graph()->start()); ReplaceNode(node, low_node, high_node); break; } - // kExprI64Mul: case IrOpcode::kInt64Mul: { DCHECK(node->InputCount() == 2); @@ -317,16 +375,13 @@ void Int64Lowering::LowerNode(Node* node) { NodeProperties::ChangeOp(node, machine()->Int32PairMul()); // 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); + Node* low_node = + graph()->NewNode(common()->Projection(0), node, graph()->start()); + Node* high_node = + graph()->NewNode(common()->Projection(1), node, graph()->start()); ReplaceNode(node, low_node, high_node); break; } - // kExprI64DivS: - // kExprI64DivU: - // kExprI64RemS: - // kExprI64RemU: - // kExprI64Ior: case IrOpcode::kWord64Or: { DCHECK(node->InputCount() == 2); Node* left = node->InputAt(0); @@ -341,8 +396,6 @@ void Int64Lowering::LowerNode(Node* node) { ReplaceNode(node, low_node, high_node); break; } - - // kExprI64Xor: case IrOpcode::kWord64Xor: { DCHECK(node->InputCount() == 2); Node* left = node->InputAt(0); @@ -357,7 +410,6 @@ void Int64Lowering::LowerNode(Node* node) { ReplaceNode(node, low_node, high_node); break; } - // kExprI64Shl: case IrOpcode::kWord64Shl: { // TODO(turbofan): if the shift count >= 32, then we can set the low word // of the output to 0 and just calculate the high word. @@ -375,12 +427,13 @@ void Int64Lowering::LowerNode(Node* node) { NodeProperties::ChangeOp(node, machine()->Word32PairShl()); // 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); + Node* low_node = + graph()->NewNode(common()->Projection(0), node, graph()->start()); + Node* high_node = + graph()->NewNode(common()->Projection(1), node, graph()->start()); ReplaceNode(node, low_node, high_node); break; } - // kExprI64ShrU: case IrOpcode::kWord64Shr: { // TODO(turbofan): if the shift count >= 32, then we can set the low word // of the output to 0 and just calculate the high word. @@ -398,12 +451,13 @@ void Int64Lowering::LowerNode(Node* node) { NodeProperties::ChangeOp(node, machine()->Word32PairShr()); // 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); + Node* low_node = + graph()->NewNode(common()->Projection(0), node, graph()->start()); + Node* high_node = + graph()->NewNode(common()->Projection(1), node, graph()->start()); ReplaceNode(node, low_node, high_node); break; } - // kExprI64ShrS: case IrOpcode::kWord64Sar: { // TODO(turbofan): if the shift count >= 32, then we can set the low word // of the output to 0 and just calculate the high word. @@ -421,12 +475,13 @@ void Int64Lowering::LowerNode(Node* node) { NodeProperties::ChangeOp(node, machine()->Word32PairSar()); // 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); + Node* low_node = + graph()->NewNode(common()->Projection(0), node, graph()->start()); + Node* high_node = + graph()->NewNode(common()->Projection(1), node, graph()->start()); ReplaceNode(node, low_node, high_node); break; } - // kExprI64Eq: case IrOpcode::kWord64Equal: { DCHECK(node->InputCount() == 2); Node* left = node->InputAt(0); @@ -446,7 +501,6 @@ void Int64Lowering::LowerNode(Node* node) { ReplaceNode(node, replacement, nullptr); break; } - // kExprI64LtS: case IrOpcode::kInt64LessThan: { LowerComparison(node, machine()->Int32LessThan(), machine()->Uint32LessThan()); @@ -467,8 +521,6 @@ void Int64Lowering::LowerNode(Node* node) { machine()->Uint32LessThanOrEqual()); break; } - - // kExprI64SConvertI32: case IrOpcode::kChangeInt32ToInt64: { DCHECK(node->InputCount() == 1); Node* input = node->InputAt(0); @@ -483,7 +535,6 @@ void Int64Lowering::LowerNode(Node* node) { node->NullAllInputs(); break; } - // kExprI64UConvertI32: { case IrOpcode::kChangeUint32ToUint64: { DCHECK(node->InputCount() == 1); Node* input = node->InputAt(0); @@ -494,7 +545,6 @@ void Int64Lowering::LowerNode(Node* node) { node->NullAllInputs(); break; } - // kExprF64ReinterpretI64: case IrOpcode::kBitcastInt64ToFloat64: { DCHECK(node->InputCount() == 1); Node* input = node->InputAt(0); @@ -505,14 +555,16 @@ void Int64Lowering::LowerNode(Node* node) { machine()->Store( StoreRepresentation(MachineRepresentation::kWord32, WriteBarrierKind::kNoWriteBarrier)), - stack_slot, graph()->NewNode(common()->Int32Constant(4)), + stack_slot, + graph()->NewNode(common()->Int32Constant(kHigherWordOffset)), GetReplacementHigh(input), graph()->start(), graph()->start()); Node* store_low_word = graph()->NewNode( machine()->Store( StoreRepresentation(MachineRepresentation::kWord32, WriteBarrierKind::kNoWriteBarrier)), - stack_slot, graph()->NewNode(common()->Int32Constant(0)), + stack_slot, + graph()->NewNode(common()->Int32Constant(kLowerWordOffset)), GetReplacementLow(input), store_high_word, graph()->start()); Node* load = @@ -523,7 +575,6 @@ void Int64Lowering::LowerNode(Node* node) { ReplaceNode(node, load, nullptr); break; } - // kExprI64ReinterpretF64: case IrOpcode::kBitcastFloat64ToInt64: { DCHECK(node->InputCount() == 1); Node* input = node->InputAt(0); @@ -539,15 +590,15 @@ void Int64Lowering::LowerNode(Node* node) { stack_slot, graph()->NewNode(common()->Int32Constant(0)), input, graph()->start(), graph()->start()); - Node* high_node = - graph()->NewNode(machine()->Load(MachineType::Int32()), stack_slot, - graph()->NewNode(common()->Int32Constant(4)), store, - graph()->start()); + Node* high_node = graph()->NewNode( + machine()->Load(MachineType::Int32()), stack_slot, + graph()->NewNode(common()->Int32Constant(kHigherWordOffset)), store, + graph()->start()); - Node* low_node = - graph()->NewNode(machine()->Load(MachineType::Int32()), stack_slot, - graph()->NewNode(common()->Int32Constant(0)), store, - graph()->start()); + Node* low_node = graph()->NewNode( + machine()->Load(MachineType::Int32()), stack_slot, + graph()->NewNode(common()->Int32Constant(kLowerWordOffset)), store, + graph()->start()); ReplaceNode(node, low_node, high_node); break; } @@ -659,7 +710,6 @@ void Int64Lowering::LowerNode(Node* node) { } break; } - // kExprI64Clz: case IrOpcode::kWord64Clz: { DCHECK(node->InputCount() == 1); Node* input = node->InputAt(0); @@ -678,7 +728,6 @@ void Int64Lowering::LowerNode(Node* node) { ReplaceNode(node, low_node, graph()->NewNode(common()->Int32Constant(0))); break; } - // kExprI64Ctz: case IrOpcode::kWord64Ctz: { DCHECK(node->InputCount() == 1); DCHECK(machine()->Word32Ctz().IsSupported()); @@ -698,7 +747,6 @@ void Int64Lowering::LowerNode(Node* node) { ReplaceNode(node, low_node, graph()->NewNode(common()->Int32Constant(0))); break; } - // kExprI64Popcnt: case IrOpcode::kWord64Popcnt: { DCHECK(node->InputCount() == 1); Node* input = node->InputAt(0); @@ -730,6 +778,14 @@ void Int64Lowering::LowerNode(Node* node) { } break; } + case IrOpcode::kWord64ReverseBytes: { + Node* input = node->InputAt(0); + ReplaceNode(node, graph()->NewNode(machine()->Word32ReverseBytes().op(), + GetReplacementHigh(input)), + graph()->NewNode(machine()->Word32ReverseBytes().op(), + GetReplacementLow(input))); + break; + } default: { DefaultLowering(node); } } |