From 01b9f4e2d39b49a9496fc78313112abd4b5cc5cc Mon Sep 17 00:00:00 2001 From: "mstarzinger@chromium.org" Date: Wed, 3 Sep 2014 12:43:41 +0000 Subject: [PATCH] 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 --- src/compiler/machine-operator.h | 7 ++++ src/compiler/simplified-lowering.cc | 47 +++++++++++++++++------- src/compiler/simplified-lowering.h | 3 ++ test/cctest/cctest.status | 4 +- test/cctest/compiler/test-simplified-lowering.cc | 16 ++++---- 5 files changed, 54 insertions(+), 23 deletions(-) diff --git a/src/compiler/machine-operator.h b/src/compiler/machine-operator.h index 9119ed6..62d1ef0 100644 --- a/src/compiler/machine-operator.h +++ b/src/compiler/machine-operator.h @@ -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 diff --git a/src/compiler/simplified-lowering.cc b/src/compiler/simplified-lowering.cc index ab5551a..960c93a 100644 --- a/src/compiler/simplified-lowering.cc +++ b/src/compiler/simplified-lowering.cc @@ -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)); } diff --git a/src/compiler/simplified-lowering.h b/src/compiler/simplified-lowering.h index 715bb40..94766f7 100644 --- a/src/compiler/simplified-lowering.h +++ b/src/compiler/simplified-lowering.h @@ -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; diff --git a/test/cctest/cctest.status b/test/cctest/cctest.status index e1bc741..db0e837 100644 --- a/test/cctest/cctest.status +++ b/test/cctest/cctest.status @@ -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' ############################################################################## diff --git a/test/cctest/compiler/test-simplified-lowering.cc b/test/cctest/compiler/test-simplified-lowering.cc index ed0abe0..cf2eab8 100644 --- a/test/cctest/compiler/test-simplified-lowering.cc +++ b/test/cctest/compiler/test-simplified-lowering.cc @@ -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(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(t.machine()->IntLessThan()->opcode()); + IrOpcode::Value compare_le = + static_cast(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()); } -- 2.7.4