diff options
Diffstat (limited to 'deps/v8/src/compiler/change-lowering.cc')
-rw-r--r-- | deps/v8/src/compiler/change-lowering.cc | 221 |
1 files changed, 140 insertions, 81 deletions
diff --git a/deps/v8/src/compiler/change-lowering.cc b/deps/v8/src/compiler/change-lowering.cc index 0057b10f81..81af22b0f0 100644 --- a/deps/v8/src/compiler/change-lowering.cc +++ b/deps/v8/src/compiler/change-lowering.cc @@ -5,7 +5,6 @@ #include "src/compiler/change-lowering.h" #include "src/code-factory.h" -#include "src/compiler/diamond.h" #include "src/compiler/js-graph.h" #include "src/compiler/linkage.h" #include "src/compiler/machine-operator.h" @@ -47,25 +46,17 @@ Reduction ChangeLowering::Reduce(Node* node) { Node* ChangeLowering::HeapNumberValueIndexConstant() { - STATIC_ASSERT(HeapNumber::kValueOffset % kPointerSize == 0); - const int heap_number_value_offset = - ((HeapNumber::kValueOffset / kPointerSize) * (machine()->Is64() ? 8 : 4)); - return jsgraph()->IntPtrConstant(heap_number_value_offset - kHeapObjectTag); + return jsgraph()->IntPtrConstant(HeapNumber::kValueOffset - kHeapObjectTag); } Node* ChangeLowering::SmiMaxValueConstant() { - const int smi_value_size = machine()->Is32() ? SmiTagging<4>::SmiValueSize() - : SmiTagging<8>::SmiValueSize(); - return jsgraph()->Int32Constant( - -(static_cast<int>(0xffffffffu << (smi_value_size - 1)) + 1)); + return jsgraph()->Int32Constant(Smi::kMaxValue); } Node* ChangeLowering::SmiShiftBitsConstant() { - const int smi_shift_size = machine()->Is32() ? SmiTagging<4>::SmiShiftSize() - : SmiTagging<8>::SmiShiftSize(); - return jsgraph()->IntPtrConstant(smi_shift_size + kSmiTagSize); + return jsgraph()->IntPtrConstant(kSmiShiftSize + kSmiTagSize); } @@ -73,14 +64,17 @@ Node* ChangeLowering::AllocateHeapNumberWithValue(Node* value, Node* control) { // The AllocateHeapNumberStub does not use the context, so we can safely pass // in Smi zero here. Callable callable = CodeFactory::AllocateHeapNumber(isolate()); - CallDescriptor* descriptor = Linkage::GetStubCallDescriptor( - isolate(), jsgraph()->zone(), callable.descriptor(), 0, - CallDescriptor::kNoFlags); Node* target = jsgraph()->HeapConstant(callable.code()); Node* context = jsgraph()->NoContextConstant(); Node* effect = graph()->NewNode(common()->ValueEffect(1), value); - Node* heap_number = graph()->NewNode(common()->Call(descriptor), target, - context, effect, control); + if (!allocate_heap_number_operator_.is_set()) { + CallDescriptor* descriptor = Linkage::GetStubCallDescriptor( + isolate(), jsgraph()->zone(), callable.descriptor(), 0, + CallDescriptor::kNoFlags, Operator::kNoThrow); + allocate_heap_number_operator_.set(common()->Call(descriptor)); + } + Node* heap_number = graph()->NewNode(allocate_heap_number_operator_.get(), + target, context, effect, control); Node* store = graph()->NewNode( machine()->Store(StoreRepresentation(kMachFloat64, kNoWriteBarrier)), heap_number, HeapNumberValueIndexConstant(), value, heap_number, control); @@ -93,6 +87,14 @@ Node* ChangeLowering::ChangeInt32ToFloat64(Node* value) { } +Node* ChangeLowering::ChangeInt32ToSmi(Node* value) { + if (machine()->Is64()) { + value = graph()->NewNode(machine()->ChangeInt32ToInt64(), value); + } + return graph()->NewNode(machine()->WordShl(), value, SmiShiftBitsConstant()); +} + + Node* ChangeLowering::ChangeSmiToFloat64(Node* value) { return ChangeInt32ToFloat64(ChangeSmiToInt32(value)); } @@ -135,64 +137,80 @@ Node* ChangeLowering::TestNotSmi(Node* value) { } -Node* ChangeLowering::Uint32LessThanOrEqual(Node* lhs, Node* rhs) { - return graph()->NewNode(machine()->Uint32LessThanOrEqual(), lhs, rhs); -} - - -Reduction ChangeLowering::ChangeBitToBool(Node* val, Node* control) { - MachineType const type = static_cast<MachineType>(kTypeBool | kRepTagged); - return Replace(graph()->NewNode(common()->Select(type), val, +Reduction ChangeLowering::ChangeBitToBool(Node* value, Node* control) { + return Replace(graph()->NewNode(common()->Select(kMachAnyTagged), value, jsgraph()->TrueConstant(), jsgraph()->FalseConstant())); } -Reduction ChangeLowering::ChangeBoolToBit(Node* val) { - return Replace( - graph()->NewNode(machine()->WordEqual(), val, jsgraph()->TrueConstant())); +Reduction ChangeLowering::ChangeBoolToBit(Node* value) { + return Replace(graph()->NewNode(machine()->WordEqual(), value, + jsgraph()->TrueConstant())); } -Reduction ChangeLowering::ChangeFloat64ToTagged(Node* val, Node* control) { - return Replace(AllocateHeapNumberWithValue(val, control)); +Reduction ChangeLowering::ChangeFloat64ToTagged(Node* value, Node* control) { + return Replace(AllocateHeapNumberWithValue(value, control)); } Reduction ChangeLowering::ChangeInt32ToTagged(Node* value, Node* control) { - if (machine()->Is64()) { - return Replace(graph()->NewNode( - machine()->Word64Shl(), - graph()->NewNode(machine()->ChangeInt32ToInt64(), value), - SmiShiftBitsConstant())); - } else if (NodeProperties::GetBounds(value).upper->Is(Type::Signed31())) { - return Replace( - graph()->NewNode(machine()->WordShl(), value, SmiShiftBitsConstant())); + if (machine()->Is64() || + NodeProperties::GetBounds(value).upper->Is(Type::SignedSmall())) { + return Replace(ChangeInt32ToSmi(value)); } Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), value, value); + Node* ovf = graph()->NewNode(common()->Projection(1), add); + Node* branch = + graph()->NewNode(common()->Branch(BranchHint::kFalse), ovf, control); + + Node* if_true = graph()->NewNode(common()->IfTrue(), branch); + Node* vtrue = + AllocateHeapNumberWithValue(ChangeInt32ToFloat64(value), if_true); + + Node* if_false = graph()->NewNode(common()->IfFalse(), branch); + Node* vfalse = graph()->NewNode(common()->Projection(0), add); + + Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); + Node* phi = + graph()->NewNode(common()->Phi(kMachAnyTagged, 2), vtrue, vfalse, merge); - Diamond d(graph(), common(), ovf, BranchHint::kFalse); - d.Chain(control); - return Replace( - d.Phi(kMachAnyTagged, - AllocateHeapNumberWithValue(ChangeInt32ToFloat64(value), d.if_true), - graph()->NewNode(common()->Projection(0), add))); + return Replace(phi); } Reduction ChangeLowering::ChangeTaggedToUI32(Node* value, Node* control, Signedness signedness) { + if (NodeProperties::GetBounds(value).upper->Is(Type::TaggedSigned())) { + return Replace(ChangeSmiToInt32(value)); + } + const MachineType type = (signedness == kSigned) ? kMachInt32 : kMachUint32; const Operator* op = (signedness == kSigned) ? machine()->ChangeFloat64ToInt32() : machine()->ChangeFloat64ToUint32(); - Diamond d(graph(), common(), TestNotSmi(value), BranchHint::kFalse); - d.Chain(control); - return Replace( - d.Phi(type, graph()->NewNode(op, LoadHeapNumberValue(value, d.if_true)), - ChangeSmiToInt32(value))); + + if (NodeProperties::GetBounds(value).upper->Is(Type::TaggedPointer())) { + return Replace(graph()->NewNode(op, LoadHeapNumberValue(value, control))); + } + + Node* check = TestNotSmi(value); + Node* branch = + graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control); + + Node* if_true = graph()->NewNode(common()->IfTrue(), branch); + Node* vtrue = graph()->NewNode(op, LoadHeapNumberValue(value, if_true)); + + Node* if_false = graph()->NewNode(common()->IfFalse(), branch); + Node* vfalse = ChangeSmiToInt32(value); + + Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); + Node* phi = graph()->NewNode(common()->Phi(type, 2), vtrue, vfalse, merge); + + return Replace(phi); } @@ -202,6 +220,7 @@ bool CanCover(Node* value, IrOpcode::Value opcode) { if (value->opcode() != opcode) return false; bool first = true; for (Edge const edge : value->use_edges()) { + if (NodeProperties::IsControlEdge(edge)) continue; if (NodeProperties::IsEffectEdge(edge)) continue; DCHECK(NodeProperties::IsValueEdge(edge)); if (!first) return false; @@ -225,48 +244,88 @@ Reduction ChangeLowering::ChangeTaggedToFloat64(Node* value, Node* control) { Node* const effect = NodeProperties::GetEffectInput(value); Node* const control = NodeProperties::GetControlInput(value); - Diamond d1(graph(), common(), TestNotSmi(object), BranchHint::kFalse); - d1.Chain(control); + const Operator* merge_op = common()->Merge(2); + const Operator* ephi_op = common()->EffectPhi(2); + const Operator* phi_op = common()->Phi(kMachFloat64, 2); - Node* number = - OperatorProperties::HasFrameStateInput(value->op()) + Node* check1 = TestNotSmi(object); + Node* branch1 = + graph()->NewNode(common()->Branch(BranchHint::kFalse), check1, control); + + Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); + Node* vtrue1 = + FLAG_turbo_deoptimization ? graph()->NewNode(value->op(), object, context, - NodeProperties::GetFrameStateInput(value), - effect, d1.if_true) - : graph()->NewNode(value->op(), object, context, effect, - d1.if_true); - Diamond d2(graph(), common(), TestNotSmi(number)); - d2.Nest(d1, true); - Node* phi2 = d2.Phi(kMachFloat64, LoadHeapNumberValue(number, d2.if_true), - ChangeSmiToFloat64(number)); - - Node* phi1 = d1.Phi(kMachFloat64, phi2, ChangeSmiToFloat64(object)); - Node* ephi1 = d1.EffectPhi(number, effect); - - for (Edge edge : value->use_edges()) { - if (NodeProperties::IsEffectEdge(edge)) { - edge.UpdateTo(ephi1); - } + NodeProperties::GetFrameStateInput(value, 0), + effect, if_true1) + : graph()->NewNode(value->op(), object, context, effect, if_true1); + Node* etrue1 = vtrue1; + { + Node* check2 = TestNotSmi(vtrue1); + Node* branch2 = graph()->NewNode(common()->Branch(), check2, if_true1); + + Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); + Node* vtrue2 = LoadHeapNumberValue(vtrue1, if_true2); + + Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2); + Node* vfalse2 = ChangeSmiToFloat64(vtrue1); + + if_true1 = graph()->NewNode(merge_op, if_true2, if_false2); + vtrue1 = graph()->NewNode(phi_op, vtrue2, vfalse2, if_true1); } + + Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); + Node* vfalse1 = ChangeSmiToFloat64(object); + Node* efalse1 = effect; + + Node* merge1 = graph()->NewNode(merge_op, if_true1, if_false1); + Node* ephi1 = graph()->NewNode(ephi_op, etrue1, efalse1, merge1); + Node* phi1 = graph()->NewNode(phi_op, vtrue1, vfalse1, merge1); + + NodeProperties::ReplaceWithValue(value, phi1, ephi1, merge1); return Replace(phi1); } - Diamond d(graph(), common(), TestNotSmi(value), BranchHint::kFalse); - d.Chain(control); - Node* load = LoadHeapNumberValue(value, d.if_true); - Node* number = ChangeSmiToFloat64(value); - return Replace(d.Phi(kMachFloat64, load, number)); + Node* check = TestNotSmi(value); + Node* branch = + graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control); + + Node* if_true = graph()->NewNode(common()->IfTrue(), branch); + Node* vtrue = LoadHeapNumberValue(value, if_true); + + Node* if_false = graph()->NewNode(common()->IfFalse(), branch); + Node* vfalse = ChangeSmiToFloat64(value); + + Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); + Node* phi = + graph()->NewNode(common()->Phi(kMachFloat64, 2), vtrue, vfalse, merge); + + return Replace(phi); } Reduction ChangeLowering::ChangeUint32ToTagged(Node* value, Node* control) { - Diamond d(graph(), common(), - Uint32LessThanOrEqual(value, SmiMaxValueConstant()), - BranchHint::kTrue); - d.Chain(control); - return Replace(d.Phi( - kMachAnyTagged, ChangeUint32ToSmi(value), - AllocateHeapNumberWithValue(ChangeUint32ToFloat64(value), d.if_false))); + if (NodeProperties::GetBounds(value).upper->Is(Type::UnsignedSmall())) { + return Replace(ChangeUint32ToSmi(value)); + } + + Node* check = graph()->NewNode(machine()->Uint32LessThanOrEqual(), value, + SmiMaxValueConstant()); + Node* branch = + graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); + + Node* if_true = graph()->NewNode(common()->IfTrue(), branch); + Node* vtrue = ChangeUint32ToSmi(value); + + Node* if_false = graph()->NewNode(common()->IfFalse(), branch); + Node* vfalse = + AllocateHeapNumberWithValue(ChangeUint32ToFloat64(value), if_false); + + Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); + Node* phi = + graph()->NewNode(common()->Phi(kMachAnyTagged, 2), vtrue, vfalse, merge); + + return Replace(phi); } |