Revision: 24180
Author: [email protected]
Date: Wed Sep 24 11:55:07 2014 UTC
Log: Add support for Float32 representation changes.
[email protected]
BUG=v8:3589
LOG=n
Review URL: https://codereview.chromium.org/598963002
https://code.google.com/p/v8/source/detail?r=24180
Modified:
/branches/bleeding_edge/src/compiler/js-graph.cc
/branches/bleeding_edge/src/compiler/js-graph.h
/branches/bleeding_edge/src/compiler/js-typed-lowering.cc
/branches/bleeding_edge/src/compiler/representation-change.h
/branches/bleeding_edge/test/cctest/compiler/test-representation-change.cc
=======================================
--- /branches/bleeding_edge/src/compiler/js-graph.cc Wed Sep 10 12:23:45
2014 UTC
+++ /branches/bleeding_edge/src/compiler/js-graph.cc Wed Sep 24 11:55:07
2014 UTC
@@ -163,6 +163,12 @@
}
return *loc;
}
+
+
+Node* JSGraph::Float32Constant(float value) {
+ // TODO(turbofan): cache float32 constants.
+ return NewNode(common()->Float32Constant(value));
+}
Node* JSGraph::Float64Constant(double value) {
=======================================
--- /branches/bleeding_edge/src/compiler/js-graph.h Mon Sep 22 07:17:13
2014 UTC
+++ /branches/bleeding_edge/src/compiler/js-graph.h Wed Sep 24 11:55:07
2014 UTC
@@ -68,6 +68,9 @@
Node* Uint32Constant(uint32_t value) {
return Int32Constant(bit_cast<int32_t>(value));
}
+
+ // Creates a Float32Constant node, usually canonicalized.
+ Node* Float32Constant(float value);
// Creates a Float64Constant node, usually canonicalized.
Node* Float64Constant(double value);
=======================================
--- /branches/bleeding_edge/src/compiler/js-typed-lowering.cc Wed Sep 24
11:08:35 2014 UTC
+++ /branches/bleeding_edge/src/compiler/js-typed-lowering.cc Wed Sep 24
11:55:07 2014 UTC
@@ -559,14 +559,6 @@
graph()->NewNode(simplified()->LoadElement(element_access),
elements,
key, jsgraph()->Uint32Constant(length),
NodeProperties::GetEffectInput(node));
- // TODO(titzer): Remove this hack once float32 is properly supported in
- // simplified lowering.
- if (element_access.machine_type == kRepFloat32) {
- Node* change =
- graph()->NewNode(machine()->ChangeFloat32ToFloat64(), value);
- NodeProperties::ReplaceWithValue(node, change, value);
- return Changed(value);
- }
return ReplaceEagerly(node, value);
}
return NoChange();
@@ -610,11 +602,7 @@
NodeProperties::GetControlInput(node));
Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
- // TODO(titzer): Remove this hack once float32 is properly supported in
- // simplified lowering.
- if (element_access.machine_type == kRepFloat32) {
- value = graph()->NewNode(machine()->TruncateFloat64ToFloat32(),
value);
- }
+
Node* store =
graph()->NewNode(simplified()->StoreElement(element_access),
elements,
key, jsgraph()->Uint32Constant(length), value,
=======================================
--- /branches/bleeding_edge/src/compiler/representation-change.h Wed Sep 24
11:08:35 2014 UTC
+++ /branches/bleeding_edge/src/compiler/representation-change.h Wed Sep 24
11:55:07 2014 UTC
@@ -88,6 +88,8 @@
}
case IrOpcode::kFloat64Constant:
return jsgraph()->Constant(OpParameter<double>(node));
+ case IrOpcode::kFloat32Constant:
+ return jsgraph()->Constant(OpParameter<float>(node));
default:
break;
}
@@ -103,9 +105,8 @@
} else {
return TypeError(node, output_type, kRepTagged);
}
- } else if (output_type & kRepFloat32) {
- node =
jsgraph()->graph()->NewNode(machine()->ChangeFloat32ToFloat64(),
- node);
+ } else if (output_type & kRepFloat32) { // float32 -> float64 ->
tagged
+ node = InsertChangeFloat32ToFloat64(node);
op = simplified()->ChangeFloat64ToTagged();
} else if (output_type & kRepFloat64) {
op = simplified()->ChangeFloat64ToTagged();
@@ -118,14 +119,47 @@
Node* GetFloat32RepresentationFor(Node* node, MachineTypeUnion
output_type) {
// Eagerly fold representation changes for constants.
switch (node->opcode()) {
- // TODO(turbofan): NumberConstant, Int32Constant, and
Float64Constant?
+ case IrOpcode::kFloat64Constant:
+ case IrOpcode::kNumberConstant:
+ return jsgraph()->Float32Constant(
+ DoubleToFloat32(OpParameter<double>(node)));
+ case IrOpcode::kInt32Constant:
+ if (output_type & kTypeUint32) {
+ uint32_t value = OpParameter<uint32_t>(node);
+ return jsgraph()->Float32Constant(value);
+ } else {
+ int32_t value = OpParameter<int32_t>(node);
+ return jsgraph()->Float32Constant(value);
+ }
case IrOpcode::kFloat32Constant:
return node; // No change necessary.
default:
break;
}
- // TODO(turbofan): Select the correct X -> Float32 operator.
- return TypeError(node, output_type, kRepFloat32);
+ // Select the correct X -> Float32 operator.
+ const Operator* op;
+ if (output_type & kRepBit) {
+ return TypeError(node, output_type, kRepFloat32);
+ } else if (output_type & rWord) {
+ if (output_type & kTypeUint32) {
+ op = machine()->ChangeUint32ToFloat64();
+ } else {
+ op = machine()->ChangeInt32ToFloat64();
+ }
+ // int32 -> float64 -> float32
+ node = jsgraph()->graph()->NewNode(op, node);
+ op = machine()->TruncateFloat64ToFloat32();
+ } else if (output_type & kRepTagged) {
+ op = simplified()
+ ->ChangeTaggedToFloat64(); // tagged -> float64 -> float32
+ node = jsgraph()->graph()->NewNode(op, node);
+ op = machine()->TruncateFloat64ToFloat32();
+ } else if (output_type & kRepFloat64) {
+ op = machine()->ChangeFloat32ToFloat64();
+ } else {
+ return TypeError(node, output_type, kRepFloat32);
+ }
+ return jsgraph()->graph()->NewNode(op, node);
}
Node* GetFloat64RepresentationFor(Node* node, MachineTypeUnion
output_type) {
@@ -143,6 +177,8 @@
}
case IrOpcode::kFloat64Constant:
return node; // No change necessary.
+ case IrOpcode::kFloat32Constant:
+ return jsgraph()->Float64Constant(OpParameter<float>(node));
default:
break;
}
@@ -165,6 +201,18 @@
}
return jsgraph()->graph()->NewNode(op, node);
}
+
+ Node* MakeInt32Constant(double value) {
+ if (value < 0) {
+ DCHECK(IsInt32Double(value));
+ int32_t iv = static_cast<int32_t>(value);
+ return jsgraph()->Int32Constant(iv);
+ } else {
+ DCHECK(IsUint32Double(value));
+ int32_t iv = static_cast<int32_t>(static_cast<uint32_t>(value));
+ return jsgraph()->Int32Constant(iv);
+ }
+ }
Node* GetWord32RepresentationFor(Node* node, MachineTypeUnion
output_type,
bool use_unsigned) {
@@ -173,18 +221,10 @@
case IrOpcode::kInt32Constant:
return node; // No change necessary.
case IrOpcode::kNumberConstant:
- case IrOpcode::kFloat64Constant: {
- double value = OpParameter<double>(node);
- if (value < 0) {
- DCHECK(IsInt32Double(value));
- int32_t iv = static_cast<int32_t>(value);
- return jsgraph()->Int32Constant(iv);
- } else {
- DCHECK(IsUint32Double(value));
- int32_t iv = static_cast<int32_t>(static_cast<uint32_t>(value));
- return jsgraph()->Int32Constant(iv);
- }
- }
+ case IrOpcode::kFloat32Constant:
+ return MakeInt32Constant(OpParameter<float>(node));
+ case IrOpcode::kFloat64Constant:
+ return MakeInt32Constant(OpParameter<double>(node));
default:
break;
}
@@ -196,6 +236,13 @@
} else {
op = machine()->ChangeFloat64ToInt32();
}
+ } else if (output_type & kRepFloat32) {
+ node = InsertChangeFloat32ToFloat64(node); // float32 -> float64 ->
int32
+ if (output_type & kTypeUint32 || use_unsigned) {
+ op = machine()->ChangeFloat64ToUint32();
+ } else {
+ op = machine()->ChangeFloat64ToInt32();
+ }
} else if (output_type & kRepTagged) {
if (output_type & kTypeUint32 || use_unsigned) {
op = simplified()->ChangeTaggedToUint32();
@@ -366,6 +413,11 @@
}
return node;
}
+
+ Node* InsertChangeFloat32ToFloat64(Node* node) {
+ return jsgraph()->graph()->NewNode(machine()->ChangeFloat32ToFloat64(),
+ node);
+ }
JSGraph* jsgraph() { return jsgraph_; }
Isolate* isolate() { return isolate_; }
=======================================
---
/branches/bleeding_edge/test/cctest/compiler/test-representation-change.cc
Wed Sep 24 11:08:35 2014 UTC
+++
/branches/bleeding_edge/test/cctest/compiler/test-representation-change.cc
Wed Sep 24 11:55:07 2014 UTC
@@ -88,7 +88,6 @@
} // namespace v8::internal::compiler
-// TODO(titzer): add kRepFloat32 when fully supported.
static const MachineType all_reps[] = {kRepBit, kRepWord32,
kRepWord64,
kRepFloat32, kRepFloat64,
kRepTagged};
@@ -147,6 +146,13 @@
Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64,
kRepTagged);
r.CheckNumberConstant(c, double_inputs[i]);
}
+
+ for (size_t i = 0; i < arraysize(double_inputs); i++) {
+ volatile float fval = static_cast<float>(double_inputs[i]);
+ Node* n = r.jsgraph()->Float32Constant(fval);
+ Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32,
kRepTagged);
+ r.CheckNumberConstant(c, fval);
+ }
for (size_t i = 0; i < arraysize(int32_inputs); i++) {
Node* n = r.jsgraph()->Int32Constant(int32_inputs[i]);
@@ -175,6 +181,23 @@
CHECK_EQ(expected, c->opcode());
CHECK_EQ(n, c->InputAt(0));
}
+
+
+static void CheckTwoChanges(IrOpcode::Value expected2,
+ IrOpcode::Value expected1, MachineTypeUnion
from,
+ MachineTypeUnion to) {
+ RepresentationChangerTester r;
+
+ Node* n = r.Parameter();
+ Node* c1 = r.changer()->GetRepresentationFor(n, from, to);
+
+ CHECK_NE(c1, n);
+ CHECK_EQ(expected1, c1->opcode());
+ Node* c2 = c1->InputAt(0);
+ CHECK_NE(c2, n);
+ CHECK_EQ(expected2, c2->opcode());
+ CHECK_EQ(n, c2->InputAt(0));
+}
TEST(SingleChanges) {
@@ -202,7 +225,30 @@
kRepWord32);
CheckChange(IrOpcode::kChangeFloat64ToUint32, kRepFloat64 | kTypeUint32,
kRepWord32);
+
+ // Int32,Uint32 <-> Float32 require two changes.
+ CheckTwoChanges(IrOpcode::kChangeInt32ToFloat64,
+ IrOpcode::kTruncateFloat64ToFloat32, kRepWord32 |
kTypeInt32,
+ kRepFloat32);
+ CheckTwoChanges(IrOpcode::kChangeUint32ToFloat64,
+ IrOpcode::kTruncateFloat64ToFloat32, kRepWord32 |
kTypeUint32,
+ kRepFloat32);
+ CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
+ IrOpcode::kChangeFloat64ToInt32, kRepFloat32 |
kTypeInt32,
+ kRepWord32);
+ CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
+ IrOpcode::kChangeFloat64ToUint32, kRepFloat32 |
kTypeUint32,
+ kRepWord32);
+
+ // Float32 <-> Tagged require two changes.
+ CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
+ IrOpcode::kChangeFloat64ToTagged, kRepFloat32,
kRepTagged);
+ CheckTwoChanges(IrOpcode::kChangeTaggedToFloat64,
+ IrOpcode::kTruncateFloat64ToFloat32, kRepTagged,
kRepFloat32);
}
+
+
+// TODO(titzer): test constant folding of changes between int/float
TEST(SignednessInWord32) {
@@ -215,6 +261,11 @@
kRepWord32 | kTypeUint32);
CheckChange(IrOpcode::kChangeInt32ToFloat64, kRepWord32, kRepFloat64);
CheckChange(IrOpcode::kChangeFloat64ToInt32, kRepFloat64, kRepWord32);
+
+ CheckTwoChanges(IrOpcode::kChangeInt32ToFloat64,
+ IrOpcode::kTruncateFloat64ToFloat32, kRepWord32,
kRepFloat32);
+ CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
+ IrOpcode::kChangeFloat64ToInt32, kRepFloat32,
kRepWord32);
}
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.