Lower simplified StringLessThan[OrEqual] to runtime call.

R=titzer@chromium.org
TEST=cctest/test-simplified-lowering/LowerStringOps_to_call_and_compare

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23653 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent dd6d2e07
......@@ -60,6 +60,7 @@ class MachineOperatorBuilder {
#define UNOP(name) SIMPLE(name, Operator::kPure, 1, 1)
#define WORD_SIZE(x) return is64() ? Word64##x() : Word32##x()
#define INT_SIZE(x) return is64() ? Int64##x() : Int32##x()
Operator* Load(MachineType rep) { // load [base + index]
OP1(Load, MachineType, rep, Operator::kNoWrite, 2, 1);
......@@ -121,6 +122,11 @@ class MachineOperatorBuilder {
Operator* Int64LessThan() { BINOP(Int64LessThan); }
Operator* Int64LessThanOrEqual() { BINOP(Int64LessThanOrEqual); }
// Signed comparison of word-sized integer values, translates to int32/int64
// comparisons depending on the word-size of the machine.
Operator* IntLessThan() { INT_SIZE(LessThan); }
Operator* IntLessThanOrEqual() { INT_SIZE(LessThanOrEqual); }
// Convert representation of integers between float64 and int32/uint32.
// The precise rounding mode and handling of out of range inputs are *not*
// defined for these operators, since they are intended only for use with
......@@ -157,6 +163,7 @@ class MachineOperatorBuilder {
inline MachineType word() const { return word_; }
#undef WORD_SIZE
#undef INT_SIZE
#undef UNOP
#undef BINOP
#undef OP1
......
......@@ -526,12 +526,12 @@ class RepresentationSelector {
}
case IrOpcode::kStringLessThan: {
VisitBinop(node, kMachAnyTagged, kRepBit);
// TODO(titzer): lower StringLessThan to stub/runtime call.
if (lower()) lowering->DoStringLessThan(node);
break;
}
case IrOpcode::kStringLessThanOrEqual: {
VisitBinop(node, kMachAnyTagged, kRepBit);
// TODO(titzer): lower StringLessThanOrEqual to stub/runtime call.
if (lower()) lowering->DoStringLessThanOrEqual(node);
break;
}
case IrOpcode::kStringAdd: {
......@@ -855,23 +855,42 @@ void SimplifiedLowering::DoStringAdd(Node* node) {
}
void SimplifiedLowering::DoStringEqual(Node* node) {
Node* SimplifiedLowering::StringComparison(Node* node, bool requires_ordering) {
CEntryStub stub(zone()->isolate(), 1);
ExternalReference ref(Runtime::kStringEquals, zone()->isolate());
Runtime::FunctionId f =
requires_ordering ? Runtime::kStringCompare : Runtime::kStringEquals;
ExternalReference ref(f, zone()->isolate());
Operator::Properties props = node->op()->properties();
// TODO(mstarzinger): We should call StringCompareStub here instead, once an
// interface descriptor is available for it.
CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
Runtime::kStringEquals, 2, props, zone());
Node* call = graph()->NewNode(common()->Call(desc),
jsgraph()->HeapConstant(stub.GetCode()),
NodeProperties::GetValueInput(node, 0),
NodeProperties::GetValueInput(node, 1),
jsgraph()->ExternalConstant(ref),
jsgraph()->Int32Constant(2),
jsgraph()->UndefinedConstant());
CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(f, 2, props, zone());
return graph()->NewNode(common()->Call(desc),
jsgraph()->HeapConstant(stub.GetCode()),
NodeProperties::GetValueInput(node, 0),
NodeProperties::GetValueInput(node, 1),
jsgraph()->ExternalConstant(ref),
jsgraph()->Int32Constant(2),
jsgraph()->UndefinedConstant());
}
void SimplifiedLowering::DoStringEqual(Node* node) {
node->set_op(machine()->WordEqual());
node->ReplaceInput(0, call);
node->ReplaceInput(0, StringComparison(node, false));
node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL));
}
void SimplifiedLowering::DoStringLessThan(Node* node) {
node->set_op(machine()->IntLessThan());
node->ReplaceInput(0, StringComparison(node, true));
node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL));
}
void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) {
node->set_op(machine()->IntLessThanOrEqual());
node->ReplaceInput(0, StringComparison(node, true));
node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL));
}
......
......@@ -29,6 +29,8 @@ class SimplifiedLowering {
void DoStoreElement(Node* node);
void DoStringAdd(Node* node);
void DoStringEqual(Node* node);
void DoStringLessThan(Node* node);
void DoStringLessThanOrEqual(Node* node);
private:
JSGraph* jsgraph_;
......@@ -39,6 +41,7 @@ class SimplifiedLowering {
Node* Untag(Node* node);
Node* OffsetMinusTagConstant(int32_t offset);
Node* ComputeIndex(const ElementAccess& access, Node* index);
Node* StringComparison(Node* node, bool requires_ordering);
friend class RepresentationSelector;
......
......@@ -300,7 +300,7 @@
'test-serialize/DeserializeFromSecondSerialization': [SKIP],
# Test requires turbofan:
'test-simplified-lowering/LowerStringOps_to_call_and_wordeq': [SKIP],
'test-simplified-lowering/LowerStringOps_to_call_and_compare': [SKIP],
}], # 'arch == mipsel or arch == mips'
##############################################################################
......@@ -319,7 +319,7 @@
'test-serialize/DeserializeFromSecondSerialization': [SKIP],
# Test requires turbofan:
'test-simplified-lowering/LowerStringOps_to_call_and_wordeq': [SKIP],
'test-simplified-lowering/LowerStringOps_to_call_and_compare': [SKIP],
}], # 'arch == mips64el'
##############################################################################
......
......@@ -1051,15 +1051,17 @@ TEST(LowerReferenceEqual_to_wordeq) {
}
TEST(LowerStringOps_to_call_and_wordeq) {
TEST(LowerStringOps_to_call_and_compare) {
TestingGraph t(Type::String(), Type::String());
IrOpcode::Value opcode =
IrOpcode::Value compare_eq =
static_cast<IrOpcode::Value>(t.machine()->WordEqual()->opcode());
t.CheckLoweringBinop(opcode, t.simplified()->StringEqual());
if (false) { // TODO(titzer): lower StringOps to stub/runtime calls
t.CheckLoweringBinop(opcode, t.simplified()->StringLessThan());
t.CheckLoweringBinop(opcode, t.simplified()->StringLessThanOrEqual());
}
IrOpcode::Value compare_lt =
static_cast<IrOpcode::Value>(t.machine()->IntLessThan()->opcode());
IrOpcode::Value compare_le =
static_cast<IrOpcode::Value>(t.machine()->IntLessThanOrEqual()->opcode());
t.CheckLoweringBinop(compare_eq, t.simplified()->StringEqual());
t.CheckLoweringBinop(compare_lt, t.simplified()->StringLessThan());
t.CheckLoweringBinop(compare_le, t.simplified()->StringLessThanOrEqual());
t.CheckLoweringBinop(IrOpcode::kCall, t.simplified()->StringAdd());
}
......
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