MIPS: Fix 'MIPS: [turbofan] Optimize certain chains of Branch into a Switch.'
authorbalazs.kilvady <balazs.kilvady@imgtec.com>
Wed, 18 Feb 2015 18:41:46 +0000 (10:41 -0800)
committerCommit bot <commit-bot@chromium.org>
Wed, 18 Feb 2015 18:41:56 +0000 (18:41 +0000)
Space and time constants fixed. Delay slot optimisations added.

BUG=

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

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

src/compiler/mips/code-generator-mips.cc
src/compiler/mips/instruction-selector-mips.cc
src/compiler/mips64/code-generator-mips64.cc
src/compiler/mips64/instruction-selector-mips64.cc

index 856a69d..58c4581 100644 (file)
@@ -889,9 +889,10 @@ void CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) {
   MipsOperandConverter i(this, instr);
   Register input = i.InputRegister(0);
   for (size_t index = 2; index < instr->InputCount(); index += 2) {
-    __ Branch(GetLabel(i.InputRpo(index + 1)), eq, input,
-              Operand(i.InputInt32(index + 0)));
+    __ li(at, Operand(i.InputInt32(index + 0)));
+    __ beq(input, at, GetLabel(i.InputRpo(index + 1)));
   }
+  __ nop();  // Branch delay slot of the last beq.
   AssembleArchJump(i.InputRpo(1));
 }
 
@@ -902,12 +903,12 @@ void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) {
   size_t const case_count = instr->InputCount() - 2;
   Label here;
   __ Branch(GetLabel(i.InputRpo(1)), hs, input, Operand(case_count));
+  __ BlockTrampolinePoolFor(case_count + 6);
   __ bal(&here);
-  __ nop();  // Branch delay slot nop.
+  __ sll(at, input, 2);  // Branch delay slot.
   __ bind(&here);
-  __ sll(at, input, 2);
   __ addu(at, at, ra);
-  __ lw(at, MemOperand(at, 5 * v8::internal::Assembler::kInstrSize));
+  __ lw(at, MemOperand(at, 4 * v8::internal::Assembler::kInstrSize));
   __ jr(at);
   __ nop();  // Branch delay slot nop.
   for (size_t index = 0; index < case_count; ++index) {
index 30fcb80..d723453 100644 (file)
@@ -761,9 +761,9 @@ void InstructionSelector::VisitSwitch(Node* node, BasicBlock* default_branch,
 
   // Determine whether to issue an ArchTableSwitch or an ArchLookupSwitch
   // instruction.
-  size_t table_space_cost = 4 + value_range;
-  size_t table_time_cost = 3;
-  size_t lookup_space_cost = 3 + 2 * case_count;
+  size_t table_space_cost = 9 + value_range;
+  size_t table_time_cost = 9;
+  size_t lookup_space_cost = 2 + 2 * case_count;
   size_t lookup_time_cost = case_count;
   if (case_count > 0 &&
       table_space_cost + 3 * table_time_cost <=
index 7c1288d..60e016f 100644 (file)
@@ -1044,9 +1044,10 @@ void CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) {
   MipsOperandConverter i(this, instr);
   Register input = i.InputRegister(0);
   for (size_t index = 2; index < instr->InputCount(); index += 2) {
-    __ Branch(GetLabel(i.InputRpo(index + 1)), eq, input,
-              Operand(i.InputInt32(index + 0)));
+    __ li(at, Operand(i.InputInt32(index + 0)));
+    __ beq(input, at, GetLabel(i.InputRpo(index + 1)));
   }
+  __ nop();  // Branch delay slot of the last beq.
   AssembleArchJump(i.InputRpo(1));
 }
 
@@ -1058,16 +1059,16 @@ void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) {
   Label here;
 
   __ Branch(GetLabel(i.InputRpo(1)), hs, input, Operand(case_count));
-  // Ensure that dd-ed labels goes to 8 byte aligned addresses.
-  if ((masm()->pc_offset() & 7) == 0) {
+  __ BlockTrampolinePoolFor(case_count * 2 + 7);
+  // Ensure that dd-ed labels use 8 byte aligned addresses.
+  if ((masm()->pc_offset() & 7) != 0) {
     __ nop();
   }
   __ bal(&here);
-  __ nop();  // Branch delay slot nop.
+  __ dsll(at, input, 3);  // Branch delay slot.
   __ bind(&here);
-  __ dsll(at, input, 3);
   __ daddu(at, at, ra);
-  __ ld(at, MemOperand(at, 5 * v8::internal::Assembler::kInstrSize));
+  __ ld(at, MemOperand(at, 4 * v8::internal::Assembler::kInstrSize));
   __ jr(at);
   __ nop();  // Branch delay slot nop.
   for (size_t index = 0; index < case_count; ++index) {
index 713deb6..779f786 100644 (file)
@@ -982,9 +982,9 @@ void InstructionSelector::VisitSwitch(Node* node, BasicBlock* default_branch,
 
   // Determine whether to issue an ArchTableSwitch or an ArchLookupSwitch
   // instruction.
-  size_t table_space_cost = 4 + value_range;
-  size_t table_time_cost = 3;
-  size_t lookup_space_cost = 3 + 2 * case_count;
+  size_t table_space_cost = 10 + 2 * value_range;
+  size_t table_time_cost = 10;
+  size_t lookup_space_cost = 2 + 2 * case_count;
   size_t lookup_time_cost = case_count;
   if (case_count > 0 &&
       table_space_cost + 3 * table_time_cost <=