| Index: src/compiler/simplified-lowering.cc
|
| diff --git a/src/compiler/simplified-lowering.cc b/src/compiler/simplified-lowering.cc
|
| index bf19aec68d28e0e7a3a6fdb6f5fcff8e2caf1ba1..4bfe1e27cac77a881951fc5020693ae9fc781d15 100644
|
| --- a/src/compiler/simplified-lowering.cc
|
| +++ b/src/compiler/simplified-lowering.cc
|
| @@ -5,59 +5,190 @@
|
| #include "src/compiler/simplified-lowering.h"
|
|
|
| #include "src/compiler/graph-inl.h"
|
| +#include "src/compiler/node-properties-inl.h"
|
| #include "src/objects.h"
|
|
|
| namespace v8 {
|
| namespace internal {
|
| namespace compiler {
|
|
|
| -Node* SimplifiedLowering::DoChangeTaggedToInt32(Node* node, Node* effect,
|
| - Node* control) {
|
| - return node;
|
| +Node* SimplifiedLowering::IsTagged(Node* node) {
|
| + // TODO(titzer): factor this out to a TaggingScheme abstraction.
|
| + STATIC_ASSERT(kSmiTagMask == 1); // Only works if tag is the low bit.
|
| + return graph()->NewNode(machine()->WordAnd(), node,
|
| + jsgraph()->Int32Constant(kSmiTagMask));
|
| }
|
|
|
|
|
| -Node* SimplifiedLowering::DoChangeTaggedToUint32(Node* node, Node* effect,
|
| - Node* control) {
|
| - return node;
|
| +Node* SimplifiedLowering::Untag(Node* node) {
|
| + // TODO(titzer): factor this out to a TaggingScheme abstraction.
|
| + Node* shift_amount = jsgraph()->Int32Constant(kSmiTagSize + kSmiShiftSize);
|
| + return graph()->NewNode(machine()->WordSar(), node, shift_amount);
|
| +}
|
| +
|
| +
|
| +Node* SimplifiedLowering::SmiTag(Node* node) {
|
| + // TODO(titzer): factor this out to a TaggingScheme abstraction.
|
| + Node* shift_amount = jsgraph()->Int32Constant(kSmiTagSize + kSmiShiftSize);
|
| + return graph()->NewNode(machine()->WordShl(), node, shift_amount);
|
| }
|
|
|
|
|
| -Node* SimplifiedLowering::DoChangeTaggedToFloat64(Node* node, Node* effect,
|
| - Node* control) {
|
| - return node;
|
| +Node* SimplifiedLowering::OffsetMinusTagConstant(int32_t offset) {
|
| + return jsgraph()->Int32Constant(offset - kHeapObjectTag);
|
| }
|
|
|
|
|
| -Node* SimplifiedLowering::DoChangeInt32ToTagged(Node* node, Node* effect,
|
| - Node* control) {
|
| - return node;
|
| +static void UpdateControlSuccessors(Node* before, Node* node) {
|
| + ASSERT(IrOpcode::IsControlOpcode(before->opcode()));
|
| + UseIter iter = before->uses().begin();
|
| + while (iter != before->uses().end()) {
|
| + if (IrOpcode::IsControlOpcode((*iter)->opcode()) &&
|
| + NodeProperties::IsControlEdge(iter.edge())) {
|
| + iter = iter.UpdateToAndIncrement(node);
|
| + continue;
|
| + }
|
| + ++iter;
|
| + }
|
| }
|
|
|
|
|
| -Node* SimplifiedLowering::DoChangeUint32ToTagged(Node* node, Node* effect,
|
| +void SimplifiedLowering::DoChangeTaggedToUI32(Node* node, Node* effect,
|
| + Node* control, bool is_signed) {
|
| + // if (IsTagged(val))
|
| + // ConvertFloat64To(Int32|Uint32)(Load[kMachineFloat64](input, #value_offset))
|
| + // else Untag(val)
|
| + Node* val = node->InputAt(0);
|
| + Node* branch = graph()->NewNode(common()->Branch(), IsTagged(val), control);
|
| +
|
| + // true branch.
|
| + Node* tbranch = graph()->NewNode(common()->IfTrue(), branch);
|
| + Node* loaded = graph()->NewNode(
|
| + machine()->Load(kMachineFloat64), val,
|
| + OffsetMinusTagConstant(HeapNumber::kValueOffset), effect);
|
| + Operator* op = is_signed ? machine()->ConvertFloat64ToInt32()
|
| + : machine()->ConvertFloat64ToUint32();
|
| + Node* converted = graph()->NewNode(op, loaded);
|
| +
|
| + // false branch.
|
| + Node* fbranch = graph()->NewNode(common()->IfFalse(), branch);
|
| + Node* untagged = Untag(val);
|
| +
|
| + // merge.
|
| + Node* merge = graph()->NewNode(common()->Merge(2), tbranch, fbranch);
|
| + Node* phi = graph()->NewNode(common()->Phi(2), converted, untagged, merge);
|
| + UpdateControlSuccessors(control, merge);
|
| + branch->ReplaceInput(1, control);
|
| + node->ReplaceUses(phi);
|
| +}
|
| +
|
| +
|
| +void SimplifiedLowering::DoChangeTaggedToFloat64(Node* node, Node* effect,
|
| Node* control) {
|
| - return node;
|
| + // if (IsTagged(input)) Load[kMachineFloat64](input, #value_offset)
|
| + // else ConvertFloat64(Untag(input))
|
| + Node* val = node->InputAt(0);
|
| + Node* branch = graph()->NewNode(common()->Branch(), IsTagged(val), control);
|
| +
|
| + // true branch.
|
| + Node* tbranch = graph()->NewNode(common()->IfTrue(), branch);
|
| + Node* loaded = graph()->NewNode(
|
| + machine()->Load(kMachineFloat64), val,
|
| + OffsetMinusTagConstant(HeapNumber::kValueOffset), effect);
|
| +
|
| + // false branch.
|
| + Node* fbranch = graph()->NewNode(common()->IfFalse(), branch);
|
| + Node* untagged = Untag(val);
|
| + Node* converted =
|
| + graph()->NewNode(machine()->ConvertInt32ToFloat64(), untagged);
|
| +
|
| + // merge.
|
| + Node* merge = graph()->NewNode(common()->Merge(2), tbranch, fbranch);
|
| + Node* phi = graph()->NewNode(common()->Phi(2), loaded, converted, merge);
|
| + UpdateControlSuccessors(control, merge);
|
| + branch->ReplaceInput(1, control);
|
| + node->ReplaceUses(phi);
|
| +}
|
| +
|
| +
|
| +void SimplifiedLowering::DoChangeUI32ToTagged(Node* node, Node* effect,
|
| + Node* control, bool is_signed) {
|
| + Node* val = node->InputAt(0);
|
| + Node* is_smi = NULL;
|
| + if (is_signed) {
|
| + if (SmiValuesAre32Bits()) {
|
| + // All int32s fit in this case.
|
| + ASSERT(kPointerSize == 8);
|
| + return node->ReplaceUses(SmiTag(val));
|
| + } else {
|
| + // TODO(turbofan): use an Int32AddWithOverflow to tag and check here.
|
| + Node* lt = graph()->NewNode(machine()->Int32LessThanOrEqual(), val,
|
| + jsgraph()->Int32Constant(Smi::kMaxValue));
|
| + Node* gt =
|
| + graph()->NewNode(machine()->Int32LessThanOrEqual(),
|
| + jsgraph()->Int32Constant(Smi::kMinValue), val);
|
| + is_smi = graph()->NewNode(machine()->Word32And(), lt, gt);
|
| + }
|
| + } else {
|
| + // Check if Uint32 value is in the smi range.
|
| + is_smi = graph()->NewNode(machine()->Uint32LessThanOrEqual(), val,
|
| + jsgraph()->Int32Constant(Smi::kMaxValue));
|
| + }
|
| +
|
| + // TODO(turbofan): fold smi test branch eagerly.
|
| + // if (IsSmi(input)) SmiTag(input);
|
| + // else InlineAllocAndInitHeapNumber(ConvertToFloat64(input)))
|
| + Node* branch = graph()->NewNode(common()->Branch(), is_smi, control);
|
| +
|
| + // true branch.
|
| + Node* tbranch = graph()->NewNode(common()->IfTrue(), branch);
|
| + Node* smi_tagged = SmiTag(val);
|
| +
|
| + // false branch.
|
| + Node* fbranch = graph()->NewNode(common()->IfFalse(), branch);
|
| + Node* heap_num = jsgraph()->Constant(0.0); // TODO(titzer): alloc and init
|
| +
|
| + // merge.
|
| + Node* merge = graph()->NewNode(common()->Merge(2), tbranch, fbranch);
|
| + Node* phi = graph()->NewNode(common()->Phi(2), smi_tagged, heap_num, merge);
|
| + UpdateControlSuccessors(control, merge);
|
| + branch->ReplaceInput(1, control);
|
| + node->ReplaceUses(phi);
|
| }
|
|
|
|
|
| -Node* SimplifiedLowering::DoChangeFloat64ToTagged(Node* node, Node* effect,
|
| - Node* control) {
|
| - return node;
|
| +void SimplifiedLowering::DoChangeFloat64ToTagged(Node* node, Node* effect,
|
| + Node* control) {
|
| + return; // TODO(titzer): need to call runtime to allocate in one branch
|
| }
|
|
|
|
|
| -Node* SimplifiedLowering::DoChangeBoolToBit(Node* node, Node* effect,
|
| - Node* control) {
|
| +void SimplifiedLowering::DoChangeBoolToBit(Node* node, Node* effect,
|
| + Node* control) {
|
| Node* val = node->InputAt(0);
|
| - Operator* op = machine()->WordEqual();
|
| - return graph()->NewNode(op, val, jsgraph()->TrueConstant());
|
| + Operator* op =
|
| + kPointerSize == 8 ? machine()->Word64Equal() : machine()->Word32Equal();
|
| + Node* cmp = graph()->NewNode(op, val, jsgraph()->TrueConstant());
|
| + node->ReplaceUses(cmp);
|
| }
|
|
|
|
|
| -Node* SimplifiedLowering::DoChangeBitToBool(Node* node, Node* effect,
|
| - Node* control) {
|
| - return node;
|
| +void SimplifiedLowering::DoChangeBitToBool(Node* node, Node* effect,
|
| + Node* control) {
|
| + Node* val = node->InputAt(0);
|
| + Node* branch = graph()->NewNode(common()->Branch(), val, control);
|
| +
|
| + // true branch.
|
| + Node* tbranch = graph()->NewNode(common()->IfTrue(), branch);
|
| + // false branch.
|
| + Node* fbranch = graph()->NewNode(common()->IfFalse(), branch);
|
| + // merge.
|
| + Node* merge = graph()->NewNode(common()->Merge(2), tbranch, fbranch);
|
| + Node* phi = graph()->NewNode(common()->Phi(2), jsgraph()->TrueConstant(),
|
| + jsgraph()->FalseConstant(), merge);
|
| + UpdateControlSuccessors(control, merge);
|
| + branch->ReplaceInput(1, control);
|
| + node->ReplaceUses(phi);
|
| }
|
|
|
|
|
| @@ -71,18 +202,16 @@ static WriteBarrierKind ComputeWriteBarrierKind(
|
| }
|
|
|
|
|
| -Node* SimplifiedLowering::DoLoadField(Node* node, Node* effect, Node* control) {
|
| +void SimplifiedLowering::DoLoadField(Node* node, Node* effect, Node* control) {
|
| const FieldAccess& access = FieldAccessOf(node->op());
|
| node->set_op(machine_.Load(access.representation));
|
| Node* offset =
|
| graph()->NewNode(common()->Int32Constant(access.offset - kHeapObjectTag));
|
| node->InsertInput(zone(), 1, offset);
|
| - return node;
|
| }
|
|
|
|
|
| -Node* SimplifiedLowering::DoStoreField(Node* node, Node* effect,
|
| - Node* control) {
|
| +void SimplifiedLowering::DoStoreField(Node* node, Node* effect, Node* control) {
|
| const FieldAccess& access = FieldAccessOf(node->op());
|
| WriteBarrierKind kind =
|
| ComputeWriteBarrierKind(access.representation, access.type);
|
| @@ -90,7 +219,6 @@ Node* SimplifiedLowering::DoStoreField(Node* node, Node* effect,
|
| Node* offset =
|
| graph()->NewNode(common()->Int32Constant(access.offset - kHeapObjectTag));
|
| node->InsertInput(zone(), 1, offset);
|
| - return node;
|
| }
|
|
|
|
|
| @@ -131,23 +259,21 @@ Node* SimplifiedLowering::ComputeIndex(const ElementAccess& access,
|
| }
|
|
|
|
|
| -Node* SimplifiedLowering::DoLoadElement(Node* node, Node* effect,
|
| - Node* control) {
|
| +void SimplifiedLowering::DoLoadElement(Node* node, Node* effect,
|
| + Node* control) {
|
| const ElementAccess& access = ElementAccessOf(node->op());
|
| node->set_op(machine_.Load(access.representation));
|
| node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1)));
|
| - return node;
|
| }
|
|
|
|
|
| -Node* SimplifiedLowering::DoStoreElement(Node* node, Node* effect,
|
| - Node* control) {
|
| +void SimplifiedLowering::DoStoreElement(Node* node, Node* effect,
|
| + Node* control) {
|
| const ElementAccess& access = ElementAccessOf(node->op());
|
| WriteBarrierKind kind =
|
| ComputeWriteBarrierKind(access.representation, access.type);
|
| node->set_op(machine_.Store(access.representation, kind));
|
| node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1)));
|
| - return node;
|
| }
|
|
|
|
|
| @@ -172,25 +298,25 @@ void SimplifiedLowering::Lower(Node* node) {
|
| case IrOpcode::kStringAdd:
|
| break;
|
| case IrOpcode::kChangeTaggedToInt32:
|
| - DoChangeTaggedToInt32(node, start, start);
|
| + DoChangeTaggedToUI32(node, start, start, true);
|
| break;
|
| case IrOpcode::kChangeTaggedToUint32:
|
| - DoChangeTaggedToUint32(node, start, start);
|
| + DoChangeTaggedToUI32(node, start, start, false);
|
| break;
|
| case IrOpcode::kChangeTaggedToFloat64:
|
| DoChangeTaggedToFloat64(node, start, start);
|
| break;
|
| case IrOpcode::kChangeInt32ToTagged:
|
| - DoChangeInt32ToTagged(node, start, start);
|
| + DoChangeUI32ToTagged(node, start, start, true);
|
| break;
|
| case IrOpcode::kChangeUint32ToTagged:
|
| - DoChangeUint32ToTagged(node, start, start);
|
| + DoChangeUI32ToTagged(node, start, start, false);
|
| break;
|
| case IrOpcode::kChangeFloat64ToTagged:
|
| DoChangeFloat64ToTagged(node, start, start);
|
| break;
|
| case IrOpcode::kChangeBoolToBit:
|
| - node->ReplaceUses(DoChangeBoolToBit(node, start, start));
|
| + DoChangeBoolToBit(node, start, start);
|
| break;
|
| case IrOpcode::kChangeBitToBool:
|
| DoChangeBitToBool(node, start, start);
|
|
|