| Index: src/compiler/change-lowering.cc
|
| diff --git a/src/compiler/change-lowering.cc b/src/compiler/change-lowering.cc
|
| index 4863f8fee9d9693f6507b5f803f864d3c38b8a07..03eaa398ab5da20314fb726afc31e49004453959 100644
|
| --- a/src/compiler/change-lowering.cc
|
| +++ b/src/compiler/change-lowering.cc
|
| @@ -15,16 +15,19 @@ ChangeLowering::~ChangeLowering() {}
|
|
|
| Reduction ChangeLowering::Reduce(Node* node) {
|
| Node* control = graph()->start();
|
| - Node* effect = control;
|
| switch (node->opcode()) {
|
| case IrOpcode::kChangeBitToBool:
|
| return ChangeBitToBool(node->InputAt(0), control);
|
| case IrOpcode::kChangeBoolToBit:
|
| return ChangeBoolToBit(node->InputAt(0));
|
| + case IrOpcode::kChangeFloat64ToTagged:
|
| + return ChangeFloat64ToTagged(node->InputAt(0), control);
|
| case IrOpcode::kChangeInt32ToTagged:
|
| - return ChangeInt32ToTagged(node->InputAt(0), effect, control);
|
| + return ChangeInt32ToTagged(node->InputAt(0), control);
|
| case IrOpcode::kChangeTaggedToFloat64:
|
| - return ChangeTaggedToFloat64(node->InputAt(0), effect, control);
|
| + return ChangeTaggedToFloat64(node->InputAt(0), control);
|
| + case IrOpcode::kChangeTaggedToInt32:
|
| + return ChangeTaggedToInt32(node->InputAt(0), control);
|
| default:
|
| return NoChange();
|
| }
|
| @@ -77,49 +80,67 @@ Reduction ChangeLowering::ChangeBoolToBit(Node* val) {
|
| }
|
|
|
|
|
| -Reduction ChangeLowering::ChangeInt32ToTagged(Node* val, Node* effect,
|
| - Node* control) {
|
| +Reduction ChangeLowering::ChangeFloat64ToTagged(Node* val, Node* control) {
|
| + return Replace(AllocateHeapNumberWithValue(val, control));
|
| +}
|
| +
|
| +
|
| +Reduction ChangeLowering::ChangeInt32ToTagged(Node* val, Node* control) {
|
| if (machine()->is64()) {
|
| return Replace(
|
| graph()->NewNode(machine()->WordShl(), val, SmiShiftBitsConstant()));
|
| }
|
|
|
| - Node* context = jsgraph()->SmiConstant(0);
|
| -
|
| Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), val, val);
|
| Node* ovf = graph()->NewNode(common()->Projection(1), add);
|
|
|
| Node* branch = graph()->NewNode(common()->Branch(), ovf, control);
|
|
|
| Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
|
| - Node* number = graph()->NewNode(machine()->ChangeInt32ToFloat64(), val);
|
| -
|
| - const Runtime::Function* fn =
|
| - Runtime::FunctionForId(Runtime::kAllocateHeapNumber);
|
| - DCHECK_EQ(0, fn->nargs);
|
| - CallDescriptor* desc = linkage()->GetRuntimeCallDescriptor(
|
| - fn->function_id, 0, Operator::kNoProperties);
|
| - Node* heap_number = graph()->NewNode(
|
| - common()->Call(desc), jsgraph()->CEntryStubConstant(),
|
| - jsgraph()->ExternalConstant(ExternalReference(fn, isolate())),
|
| - jsgraph()->Int32Constant(fn->nargs), context, effect, if_true);
|
| - Node* store = graph()->NewNode(
|
| - machine()->Store(kMachFloat64, kNoWriteBarrier), heap_number,
|
| - HeapNumberValueIndexConstant(), number, heap_number, if_true);
|
| - Node* finish = graph()->NewNode(common()->Finish(1), heap_number, store);
|
| + Node* heap_number = AllocateHeapNumberWithValue(
|
| + graph()->NewNode(machine()->ChangeInt32ToFloat64(), val), if_true);
|
|
|
| Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
|
| Node* smi = graph()->NewNode(common()->Projection(0), add);
|
|
|
| Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
|
| - Node* phi = graph()->NewNode(common()->Phi(2), finish, smi, merge);
|
| + Node* phi = graph()->NewNode(common()->Phi(2), heap_number, smi, merge);
|
|
|
| return Replace(phi);
|
| }
|
|
|
|
|
| -Reduction ChangeLowering::ChangeTaggedToFloat64(Node* val, Node* effect,
|
| - Node* control) {
|
| +Reduction ChangeLowering::ChangeTaggedToInt32(Node* val, Node* control) {
|
| + STATIC_ASSERT(kSmiTag == 0);
|
| + STATIC_ASSERT(kSmiTagMask == 1);
|
| +
|
| + Node* tag = graph()->NewNode(machine()->WordAnd(), val,
|
| + jsgraph()->Int32Constant(kSmiTagMask));
|
| + Node* branch = graph()->NewNode(common()->Branch(), tag, control);
|
| +
|
| + Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
|
| + Node* load = graph()->NewNode(
|
| + machine()->Load(kMachFloat64), val, HeapNumberValueIndexConstant(),
|
| + graph()->NewNode(common()->ControlEffect(), if_true));
|
| + Node* change = graph()->NewNode(machine()->ChangeFloat64ToInt32(), load);
|
| +
|
| + Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
|
| + Node* integer =
|
| + graph()->NewNode(machine()->WordSar(), val, SmiShiftBitsConstant());
|
| + Node* number =
|
| + machine()->is64()
|
| + ? graph()->NewNode(machine()->ConvertInt64ToInt32(), integer)
|
| + : integer;
|
| +
|
| + Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
|
| + Node* phi = graph()->NewNode(common()->Phi(2), change, number, merge);
|
| +
|
| + return Replace(phi);
|
| +}
|
| +
|
| +
|
| +Reduction ChangeLowering::ChangeTaggedToFloat64(Node* val, Node* control) {
|
| + STATIC_ASSERT(kSmiTag == 0);
|
| STATIC_ASSERT(kSmiTagMask == 1);
|
|
|
| Node* tag = graph()->NewNode(machine()->WordAnd(), val,
|
| @@ -157,6 +178,27 @@ CommonOperatorBuilder* ChangeLowering::common() const {
|
| return jsgraph()->common();
|
| }
|
|
|
| +
|
| +Node* ChangeLowering::AllocateHeapNumberWithValue(Node* value, Node* control) {
|
| + // The AllocateHeapNumber() runtime function does not use the context, so we
|
| + // can safely pass in Smi zero here.
|
| + Node* context = jsgraph()->ZeroConstant();
|
| + Node* effect = graph()->NewNode(common()->ValueEffect(1), value);
|
| + const Runtime::Function* function =
|
| + Runtime::FunctionForId(Runtime::kAllocateHeapNumber);
|
| + DCHECK_EQ(0, function->nargs);
|
| + CallDescriptor* desc = linkage()->GetRuntimeCallDescriptor(
|
| + function->function_id, 0, Operator::kNoProperties);
|
| + Node* heap_number = graph()->NewNode(
|
| + common()->Call(desc), jsgraph()->CEntryStubConstant(),
|
| + jsgraph()->ExternalConstant(ExternalReference(function, isolate())),
|
| + jsgraph()->Int32Constant(function->nargs), context, effect, control);
|
| + Node* store = graph()->NewNode(
|
| + machine()->Store(kMachFloat64, kNoWriteBarrier), heap_number,
|
| + HeapNumberValueIndexConstant(), value, heap_number, control);
|
| + return graph()->NewNode(common()->Finish(1), heap_number, store);
|
| +}
|
| +
|
| } // namespace compiler
|
| } // namespace internal
|
| } // namespace v8
|
|
|