MIPS64: [turbofan] Improve changes from and to Smi.
authordusan.m.milosavljevic <dusan.m.milosavljevic@gmail.com>
Tue, 8 Sep 2015 21:54:52 +0000 (14:54 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 8 Sep 2015 21:55:00 +0000 (21:55 +0000)
The instruction selection for following sequences is
improved:

  113: Word64Sar(107, 91) : Internal/Any
  114: TruncateInt64ToInt32(113) : Signed32/UntaggedSigned32
  115: ChangeInt32ToFloat64(114) : Signed32/UntaggedFloat64

TEST=unittests/InstructionSelectorTest.ChangesFromToSmi
BUG=

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

Cr-Commit-Position: refs/heads/master@{#30645}

src/compiler/mips64/instruction-selector-mips64.cc
test/unittests/compiler/mips64/instruction-selector-mips64-unittest.cc

index 9c0473f..09c3411 100644 (file)
@@ -286,6 +286,17 @@ void InstructionSelector::VisitWord32Sar(Node* node) {
 
 
 void InstructionSelector::VisitWord64Shl(Node* node) {
+  Mips64OperandGenerator g(this);
+  Int64BinopMatcher m(node);
+  if ((m.left().IsChangeInt32ToInt64() || m.left().IsChangeUint32ToUint64()) &&
+      m.right().IsInRange(32, 63)) {
+    // There's no need to sign/zero-extend to 64-bit if we shift out the upper
+    // 32 bits anyway.
+    Emit(kMips64Dshl, g.DefineSameAsFirst(node),
+         g.UseRegister(m.left().node()->InputAt(0)),
+         g.UseImmediate(m.right().node()));
+    return;
+  }
   VisitRRO(this, kMips64Dshl, node);
 }
 
@@ -529,6 +540,23 @@ void InstructionSelector::VisitChangeUint32ToUint64(Node* node) {
 
 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) {
   Mips64OperandGenerator g(this);
+  Node* value = node->InputAt(0);
+  if (CanCover(node, value)) {
+    switch (value->opcode()) {
+      case IrOpcode::kWord64Sar: {
+        Int64BinopMatcher m(value);
+        if (m.right().IsInRange(32, 63)) {
+          // After smi untagging no need for truncate. Combine sequence.
+          Emit(kMips64Dsar, g.DefineSameAsFirst(node),
+               g.UseRegister(m.left().node()), g.TempImmediate(kSmiShift));
+          return;
+        }
+        break;
+      }
+      default:
+        break;
+    }
+  }
   Emit(kMips64Ext, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)),
        g.TempImmediate(0), g.TempImmediate(32));
 }
index 00343d2..7a469b6 100644 (file)
@@ -444,6 +444,30 @@ INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
                         InstructionSelectorConversionTest,
                         ::testing::ValuesIn(kConversionInstructions));
 
+TEST_F(InstructionSelectorTest, ChangesFromToSmi) {
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return(m.TruncateInt64ToInt32(
+        m.Word64Sar(m.Parameter(0), m.Int32Constant(32))));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kMips64Dsar, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_None, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return(
+        m.Word64Shl(m.ChangeInt32ToInt64(m.Parameter(0)), m.Int32Constant(32)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kMips64Dshl, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
 
 // ----------------------------------------------------------------------------
 // Loads and stores.