Commit fa3dc0a5 authored by bmeurer@chromium.org's avatar bmeurer@chromium.org

[turbofan] Add support for ChangeTaggedToUint32 in ChangeLowering.

Also refactor some common code in ChangeLowering.

TEST=cctest,compiler-unittests
R=jarin@chromium.org

Review URL: https://codereview.chromium.org/488043002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23216 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 7c36df7b
......@@ -27,6 +27,11 @@ Reduction ChangeLowering::Reduce(Node* node) {
case IrOpcode::kChangeTaggedToFloat64:
return ChangeTaggedToFloat64(node->InputAt(0), control);
case IrOpcode::kChangeTaggedToInt32:
case IrOpcode::kChangeTaggedToUint32:
// ToInt32 and ToUint32 perform exactly the same operation, just the
// interpretation of the resulting 32 bit value is different, so we can
// use the same subgraph for both operations.
// See ECMA-262 9.5: ToInt32 and ECMA-262 9.6: ToUint32.
return ChangeTaggedToInt32(node->InputAt(0), control);
case IrOpcode::kChangeUint32ToTagged:
return ChangeUint32ToTagged(node->InputAt(0), control);
......@@ -73,6 +78,43 @@ Node* ChangeLowering::SmiShiftBitsConstant() {
}
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);
}
Node* ChangeLowering::ChangeSmiToInt32(Node* value) {
value = graph()->NewNode(machine()->WordSar(), value, SmiShiftBitsConstant());
if (machine()->is64()) {
value = graph()->NewNode(machine()->TruncateInt64ToInt32(), value);
}
return value;
}
Node* ChangeLowering::LoadHeapNumberValue(Node* value, Node* control) {
return graph()->NewNode(machine()->Load(kMachFloat64), value,
HeapNumberValueIndexConstant(),
graph()->NewNode(common()->ControlEffect(), control));
}
Reduction ChangeLowering::ChangeBitToBool(Node* val, Node* control) {
Node* branch = graph()->NewNode(common()->Branch(), val, control);
......@@ -137,18 +179,11 @@ Reduction ChangeLowering::ChangeTaggedToInt32(Node* val, Node* control) {
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()->TruncateFloat64ToInt32(), load);
Node* change = graph()->NewNode(machine()->TruncateFloat64ToInt32(),
LoadHeapNumberValue(val, if_true));
Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
Node* integer =
graph()->NewNode(machine()->WordSar(), val, SmiShiftBitsConstant());
Node* number =
machine()->is64()
? graph()->NewNode(machine()->TruncateInt64ToInt32(), integer)
: integer;
Node* number = ChangeSmiToInt32(val);
Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
Node* phi = graph()->NewNode(common()->Phi(2), change, number, merge);
......@@ -166,18 +201,11 @@ Reduction ChangeLowering::ChangeTaggedToFloat64(Node* val, Node* control) {
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* load = LoadHeapNumberValue(val, if_true);
Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
Node* integer =
graph()->NewNode(machine()->WordSar(), val, SmiShiftBitsConstant());
Node* number = graph()->NewNode(
machine()->ChangeInt32ToFloat64(),
machine()->is64()
? graph()->NewNode(machine()->TruncateInt64ToInt32(), integer)
: integer);
Node* number = graph()->NewNode(machine()->ChangeInt32ToFloat64(),
ChangeSmiToInt32(val));
Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
Node* phi = graph()->NewNode(common()->Phi(2), load, number, merge);
......@@ -223,27 +251,6 @@ 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
......@@ -26,11 +26,15 @@ class ChangeLowering V8_FINAL : public Reducer {
virtual Reduction Reduce(Node* node) V8_OVERRIDE;
protected:
private:
Node* HeapNumberValueIndexConstant();
Node* SmiMaxValueConstant();
Node* SmiShiftBitsConstant();
Node* AllocateHeapNumberWithValue(Node* value, Node* control);
Node* ChangeSmiToInt32(Node* value);
Node* LoadHeapNumberValue(Node* value, Node* control);
Reduction ChangeBitToBool(Node* val, Node* control);
Reduction ChangeBoolToBit(Node* val);
Reduction ChangeFloat64ToTagged(Node* val, Node* control);
......@@ -46,9 +50,6 @@ class ChangeLowering V8_FINAL : public Reducer {
CommonOperatorBuilder* common() const;
MachineOperatorBuilder* machine() const { return machine_; }
private:
Node* AllocateHeapNumberWithValue(Node* value, Node* control);
JSGraph* jsgraph_;
Linkage* linkage_;
MachineOperatorBuilder* machine_;
......
......@@ -289,6 +289,31 @@ TARGET_TEST_F(ChangeLowering32Test, ChangeTaggedToInt32) {
}
TARGET_TEST_F(ChangeLowering32Test, ChangeTaggedToUint32) {
STATIC_ASSERT(kSmiTag == 0);
STATIC_ASSERT(kSmiTagSize == 1);
Node* val = Parameter(0);
Node* node = graph()->NewNode(simplified()->ChangeTaggedToUint32(), val);
Reduction reduction = Reduce(node);
ASSERT_TRUE(reduction.Changed());
Node* phi = reduction.replacement();
Capture<Node*> branch, if_true;
EXPECT_THAT(
phi,
IsPhi(IsTruncateFloat64ToInt32(IsLoad(
kMachFloat64, val, IsInt32Constant(HeapNumberValueOffset()),
IsControlEffect(CaptureEq(&if_true)))),
IsWord32Sar(val, IsInt32Constant(SmiShiftAmount())),
IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))),
IsIfFalse(AllOf(
CaptureEq(&branch),
IsBranch(IsWord32And(val, IsInt32Constant(kSmiTagMask)),
graph()->start()))))));
}
TARGET_TEST_F(ChangeLowering32Test, ChangeUint32ToTagged) {
STATIC_ASSERT(kSmiTag == 0);
STATIC_ASSERT(kSmiTagSize == 1);
......@@ -399,6 +424,32 @@ TARGET_TEST_F(ChangeLowering64Test, ChangeTaggedToInt32) {
}
TARGET_TEST_F(ChangeLowering64Test, ChangeTaggedToUint32) {
STATIC_ASSERT(kSmiTag == 0);
STATIC_ASSERT(kSmiTagSize == 1);
Node* val = Parameter(0);
Node* node = graph()->NewNode(simplified()->ChangeTaggedToUint32(), val);
Reduction reduction = Reduce(node);
ASSERT_TRUE(reduction.Changed());
Node* phi = reduction.replacement();
Capture<Node*> branch, if_true;
EXPECT_THAT(
phi,
IsPhi(IsTruncateFloat64ToInt32(IsLoad(
kMachFloat64, val, IsInt32Constant(HeapNumberValueOffset()),
IsControlEffect(CaptureEq(&if_true)))),
IsTruncateInt64ToInt32(
IsWord64Sar(val, IsInt32Constant(SmiShiftAmount()))),
IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))),
IsIfFalse(AllOf(
CaptureEq(&branch),
IsBranch(IsWord64And(val, IsInt32Constant(kSmiTagMask)),
graph()->start()))))));
}
TARGET_TEST_F(ChangeLowering64Test, ChangeUint32ToTagged) {
STATIC_ASSERT(kSmiTag == 0);
STATIC_ASSERT(kSmiTagSize == 1);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment