 Chromium Code Reviews
 Chromium Code Reviews Issue 931263002:
  MIPS: [turbofan] Optimize certain chains of Branch into a Switch.  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master
    
  
    Issue 931263002:
  MIPS: [turbofan] Optimize certain chains of Branch into a Switch.  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master| OLD | NEW | 
|---|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "src/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" | 
| 6 #include "src/compiler/code-generator-impl.h" | 6 #include "src/compiler/code-generator-impl.h" | 
| 7 #include "src/compiler/gap-resolver.h" | 7 #include "src/compiler/gap-resolver.h" | 
| 8 #include "src/compiler/node-matchers.h" | 8 #include "src/compiler/node-matchers.h" | 
| 9 #include "src/mips/macro-assembler-mips.h" | 9 #include "src/mips/macro-assembler-mips.h" | 
| 10 #include "src/scopes.h" | 10 #include "src/scopes.h" | 
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 421 } | 421 } | 
| 422 | 422 | 
| 423 __ lw(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); | 423 __ lw(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); | 
| 424 __ Call(at); | 424 __ Call(at); | 
| 425 AddSafepointAndDeopt(instr); | 425 AddSafepointAndDeopt(instr); | 
| 426 break; | 426 break; | 
| 427 } | 427 } | 
| 428 case kArchJmp: | 428 case kArchJmp: | 
| 429 AssembleArchJump(i.InputRpo(0)); | 429 AssembleArchJump(i.InputRpo(0)); | 
| 430 break; | 430 break; | 
| 431 case kArchSwitch: | 431 case kArchLookupSwitch: | 
| 432 AssembleArchSwitch(instr); | 432 AssembleArchLookupSwitch(instr); | 
| 433 break; | |
| 434 case kArchTableSwitch: | |
| 435 AssembleArchTableSwitch(instr); | |
| 433 break; | 436 break; | 
| 434 case kArchNop: | 437 case kArchNop: | 
| 435 // don't emit code for nops. | 438 // don't emit code for nops. | 
| 436 break; | 439 break; | 
| 437 case kArchRet: | 440 case kArchRet: | 
| 438 AssembleReturn(); | 441 AssembleReturn(); | 
| 439 break; | 442 break; | 
| 440 case kArchStackPointer: | 443 case kArchStackPointer: | 
| 441 __ mov(i.OutputRegister(), sp); | 444 __ mov(i.OutputRegister(), sp); | 
| 442 break; | 445 break; | 
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 798 UNIMPLEMENTED(); | 801 UNIMPLEMENTED(); | 
| 799 } | 802 } | 
| 800 } | 803 } | 
| 801 | 804 | 
| 802 | 805 | 
| 803 void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) { | 806 void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) { | 
| 804 if (!IsNextInAssemblyOrder(target)) __ Branch(GetLabel(target)); | 807 if (!IsNextInAssemblyOrder(target)) __ Branch(GetLabel(target)); | 
| 805 } | 808 } | 
| 806 | 809 | 
| 807 | 810 | 
| 808 void CodeGenerator::AssembleArchSwitch(Instruction* instr) { | |
| 809 MipsOperandConverter i(this, instr); | |
| 810 int const kNumLabels = static_cast<int>(instr->InputCount() - 1); | |
| 811 v8::internal::Assembler::BlockTrampolinePoolScope block_trampoline_pool( | |
| 812 masm()); | |
| 813 Label here; | |
| 814 | |
| 815 __ bal(&here); | |
| 816 __ nop(); // Branch delay slot nop. | |
| 817 __ bind(&here); | |
| 818 __ sll(at, i.InputRegister(0), 2); | |
| 819 __ addu(at, at, ra); | |
| 820 __ lw(at, MemOperand(at, 5 * v8::internal::Assembler::kInstrSize)); | |
| 821 __ jr(at); | |
| 822 __ nop(); // Branch delay slot nop. | |
| 823 | |
| 824 for (int index = 0; index < kNumLabels; ++index) { | |
| 825 __ dd(GetLabel(i.InputRpo(index + 1))); | |
| 826 } | |
| 827 } | |
| 828 | |
| 829 | |
| 830 // Assembles boolean materializations after an instruction. | 811 // Assembles boolean materializations after an instruction. | 
| 831 void CodeGenerator::AssembleArchBoolean(Instruction* instr, | 812 void CodeGenerator::AssembleArchBoolean(Instruction* instr, | 
| 832 FlagsCondition condition) { | 813 FlagsCondition condition) { | 
| 833 MipsOperandConverter i(this, instr); | 814 MipsOperandConverter i(this, instr); | 
| 834 Label done; | 815 Label done; | 
| 835 | 816 | 
| 836 // Materialize a full 32-bit 1 or 0 value. The result register is always the | 817 // Materialize a full 32-bit 1 or 0 value. The result register is always the | 
| 837 // last output of the instruction. | 818 // last output of the instruction. | 
| 838 Label false_value; | 819 Label false_value; | 
| 839 DCHECK_NE(0u, instr->OutputCount()); | 820 DCHECK_NE(0u, instr->OutputCount()); | 
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 897 UNIMPLEMENTED(); | 878 UNIMPLEMENTED(); | 
| 898 } | 879 } | 
| 899 | 880 | 
| 900 // Fallthrough case is the false materialization. | 881 // Fallthrough case is the false materialization. | 
| 901 __ bind(&false_value); | 882 __ bind(&false_value); | 
| 902 __ li(result, Operand(0)); | 883 __ li(result, Operand(0)); | 
| 903 __ bind(&done); | 884 __ bind(&done); | 
| 904 } | 885 } | 
| 905 | 886 | 
| 906 | 887 | 
| 888 void CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) { | |
| 889 MipsOperandConverter i(this, instr); | |
| 890 Register input = i.InputRegister(0); | |
| 891 for (size_t index = 2; index < instr->InputCount(); index += 2) { | |
| 892 __ Branch(GetLabel(i.InputRpo(index + 1)), eq, input, | |
| 893 Operand(i.InputInt32(index + 0))); | |
| 894 } | |
| 895 AssembleArchJump(i.InputRpo(1)); | |
| 896 } | |
| 897 | |
| 898 | |
| 899 void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) { | |
| 900 MipsOperandConverter i(this, instr); | |
| 901 Register input = i.InputRegister(0); | |
| 902 size_t const case_count = instr->InputCount() - 2; | |
| 903 Label here; | |
| 904 __ Branch(GetLabel(i.InputRpo(1)), hs, input, Operand(case_count)); | |
| 905 __ bal(&here); | |
| 
paul.l...
2015/02/17 19:33:59
We need a BlockTrampolinePoolFor() call before thi
 | |
| 906 __ nop(); // Branch delay slot nop. | |
| 907 __ bind(&here); | |
| 908 __ sll(at, input, 2); | |
| 909 __ addu(at, at, ra); | |
| 910 __ lw(at, MemOperand(at, 5 * v8::internal::Assembler::kInstrSize)); | |
| 911 __ jr(at); | |
| 912 __ nop(); // Branch delay slot nop. | |
| 913 for (size_t index = 0; index < case_count; ++index) { | |
| 914 __ dd(GetLabel(i.InputRpo(index + 2))); | |
| 915 } | |
| 916 } | |
| 917 | |
| 918 | |
| 907 void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) { | 919 void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) { | 
| 908 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( | 920 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( | 
| 909 isolate(), deoptimization_id, Deoptimizer::LAZY); | 921 isolate(), deoptimization_id, Deoptimizer::LAZY); | 
| 910 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); | 922 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); | 
| 911 } | 923 } | 
| 912 | 924 | 
| 913 | 925 | 
| 914 void CodeGenerator::AssemblePrologue() { | 926 void CodeGenerator::AssemblePrologue() { | 
| 915 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 927 CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); | 
| 916 int stack_slots = frame()->GetSpillSlotCount(); | 928 int stack_slots = frame()->GetSpillSlotCount(); | 
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1185 } | 1197 } | 
| 1186 } | 1198 } | 
| 1187 MarkLazyDeoptSite(); | 1199 MarkLazyDeoptSite(); | 
| 1188 } | 1200 } | 
| 1189 | 1201 | 
| 1190 #undef __ | 1202 #undef __ | 
| 1191 | 1203 | 
| 1192 } // namespace compiler | 1204 } // namespace compiler | 
| 1193 } // namespace internal | 1205 } // namespace internal | 
| 1194 } // namespace v8 | 1206 } // namespace v8 | 
| OLD | NEW |