Title: [237627] trunk/Source/_javascript_Core
Revision
237627
Author
[email protected]
Date
2018-10-30 23:14:04 -0700 (Tue, 30 Oct 2018)

Log Message

[JSC][LLInt] Compact LLInt ASM code by removing unnecessary instructions
https://bugs.webkit.org/show_bug.cgi?id=191092

Reviewed by Saam Barati.

Looking through LLIntAssembly.h, we can find several inefficiencies. This patch fixes the
following things to tighten LLInt ASM code.

1. Remove unnecessary load instructions. Use jmp with BaseIndex directly.
2. Introduce strength reduction for mul instructions in offlineasm layer. This is now critical
since mul instruction is executed in `metadata` operation in LLInt. If the given immediate is
a power of two, we convert it to lshift instruction.

* llint/LowLevelInterpreter32_64.asm:
* llint/LowLevelInterpreter64.asm:
* offlineasm/arm64.rb:
* offlineasm/instructions.rb:
* offlineasm/x86.rb:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (237626 => 237627)


--- trunk/Source/_javascript_Core/ChangeLog	2018-10-31 05:45:07 UTC (rev 237626)
+++ trunk/Source/_javascript_Core/ChangeLog	2018-10-31 06:14:04 UTC (rev 237627)
@@ -1,3 +1,24 @@
+2018-10-30  Yusuke Suzuki  <[email protected]>
+
+        [JSC][LLInt] Compact LLInt ASM code by removing unnecessary instructions
+        https://bugs.webkit.org/show_bug.cgi?id=191092
+
+        Reviewed by Saam Barati.
+
+        Looking through LLIntAssembly.h, we can find several inefficiencies. This patch fixes the
+        following things to tighten LLInt ASM code.
+
+        1. Remove unnecessary load instructions. Use jmp with BaseIndex directly.
+        2. Introduce strength reduction for mul instructions in offlineasm layer. This is now critical
+        since mul instruction is executed in `metadata` operation in LLInt. If the given immediate is
+        a power of two, we convert it to lshift instruction.
+
+        * llint/LowLevelInterpreter32_64.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * offlineasm/arm64.rb:
+        * offlineasm/instructions.rb:
+        * offlineasm/x86.rb:
+
 2018-10-30  Don Olmstead  <[email protected]>
 
         [PlayStation] Enable _javascript_Core

Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm (237626 => 237627)


--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm	2018-10-31 05:45:07 UTC (rev 237626)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm	2018-10-31 06:14:04 UTC (rev 237627)
@@ -26,15 +26,13 @@
 macro nextInstruction()
     loadb [PC], t0
     leap _g_opcodeMap, t1
-    loadp [t1, t0, 4], t2
-    jmp t2, BytecodePtrTag
+    jmp [t1, t0, 4], BytecodePtrTag
 end
 
 macro nextInstructionWide()
     loadi 1[PC], t0
     leap _g_opcodeMapWide, t1
-    loadp [t1, t0, 4], t2
-    jmp t2, BytecodePtrTag
+    jmp [t1, t0, 4], BytecodePtrTag
 end
 
 macro getuOperandNarrow(op, field, dst)

Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm (237626 => 237627)


--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm	2018-10-31 05:45:07 UTC (rev 237626)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm	2018-10-31 06:14:04 UTC (rev 237627)
@@ -28,15 +28,13 @@
 macro nextInstruction()
     loadb [PB, PC, 1], t0
     leap _g_opcodeMap, t1
-    loadp [t1, t0, PtrSize], t2
-    jmp t2, BytecodePtrTag
+    jmp [t1, t0, PtrSize], BytecodePtrTag
 end
 
 macro nextInstructionWide()
     loadi 1[PB, PC, 1], t0
     leap _g_opcodeMapWide, t1
-    loadp [t1, t0, PtrSize], t2
-    jmp t2, BytecodePtrTag
+    jmp [t1, t0, PtrSize], BytecodePtrTag
 end
 
 macro getuOperandNarrow(op, field, dst)
@@ -437,17 +435,30 @@
 
 # Index and value must be different registers. Index may be clobbered.
 macro loadConstantOrVariable(size, index, value)
-    size(FirstConstantRegisterIndexNarrow, FirstConstantRegisterIndexWide, macro (FirstConstantRegisterIndex)
-        bpgteq index, FirstConstantRegisterIndex, .constant
+    macro loadNarrow()
+        bpgteq index, FirstConstantRegisterIndexNarrow, .constant
         loadq [cfr, index, 8], value
         jmp .done
     .constant:
         loadp CodeBlock[cfr], value
         loadp CodeBlock::m_constantRegisters + VectorBufferOffset[value], value
-        subp FirstConstantRegisterIndex, index
+        loadq -(FirstConstantRegisterIndexNarrow * 8)[value, index, 8], value
+    .done:
+    end
+
+    macro loadWide()
+        bpgteq index, FirstConstantRegisterIndexWide, .constant
+        loadq [cfr, index, 8], value
+        jmp .done
+    .constant:
+        loadp CodeBlock[cfr], value
+        loadp CodeBlock::m_constantRegisters + VectorBufferOffset[value], value
+        subp FirstConstantRegisterIndexWide, index
         loadq [value, index, 8], value
     .done:
-    end)
+    end
+
+    size(loadNarrow, loadWide, macro (load) load() end)
 end
 
 macro loadConstantOrVariableInt32(size, index, value, slow)

Modified: trunk/Source/_javascript_Core/offlineasm/arm64.rb (237626 => 237627)


--- trunk/Source/_javascript_Core/offlineasm/arm64.rb	2018-10-31 05:45:07 UTC (rev 237626)
+++ trunk/Source/_javascript_Core/offlineasm/arm64.rb	2018-10-31 06:14:04 UTC (rev 237627)
@@ -484,6 +484,18 @@
     $asm.puts "#{opcode} #{arm64TACOperands(operands, kind)}"
 end
 
+def emitARM64Mul(opcode, operands, kind)
+    if operands.size == 2 and operands[0].is_a? Immediate
+        imm = operands[0].value
+        if imm > 0 and isPowerOfTwo(imm)
+            emitARM64LShift([Immediate.new(nil, Math.log2(imm).to_i), operands[1]], kind)
+            return
+        end
+    end
+
+    $asm.puts "madd #{arm64TACOperands(operands, kind)}, #{arm64GPRName('xzr', kind)}"
+end
+
 def emitARM64Unflipped(opcode, operands, kind)
     $asm.puts "#{opcode} #{arm64Operands(operands, kind)}"
 end
@@ -522,6 +534,21 @@
     emitARM64TAC(opcodeRegs, operands, kind)
 end
 
+def emitARM64LShift(operands, kind)
+    emitARM64Shift("lslv", "ubfm", operands, kind) {
+        | value |
+        case kind
+        when :word
+            [32 - value, 31 - value]
+        when :ptr
+            bitSize = $currentSettings["ADDRESS64"] ? 64 : 32
+            [bitSize - value, bitSize - 1 - value]
+        when :quad
+            [64 - value, 63 - value]
+        end
+    }
+end
+
 def emitARM64Branch(opcode, operands, kind, branchOpcode)
     emitARM64Unflipped(opcode, operands[0..-2], kind)
     $asm.puts "#{branchOpcode} #{operands[-1].asmLabel}"
@@ -584,21 +611,11 @@
         when "xorq"
             emitARM64TAC("eor", operands, :quad)
         when "lshifti"
-            emitARM64Shift("lslv", "ubfm", operands, :word) {
-                | value |
-                [32 - value, 31 - value]
-            }
+            emitARM64LShift(operands, :word)
         when "lshiftp"
-            emitARM64Shift("lslv", "ubfm", operands, :ptr) {
-                | value |
-                bitSize = $currentSettings["ADDRESS64"] ? 64 : 32
-                [bitSize - value, bitSize - 1 - value]
-            }
+            emitARM64LShift(operands, :ptr)
         when "lshiftq"
-            emitARM64Shift("lslv", "ubfm", operands, :quad) {
-                | value |
-                [64 - value, 63 - value]
-            }
+            emitARM64LShift(operands, :quad)
         when "rshifti"
             emitARM64Shift("asrv", "sbfm", operands, :word) {
                 | value |
@@ -632,11 +649,11 @@
                 [value, 63]
             }
         when "muli"
-            $asm.puts "madd #{arm64TACOperands(operands, :word)}, wzr"
+            emitARM64Mul('mul', operands, :word)
         when "mulp"
-            $asm.puts "madd #{arm64TACOperands(operands, :ptr)}, #{arm64GPRName('xzr', :ptr)}"
+            emitARM64Mul('mul', operands, :ptr)
         when "mulq"
-            $asm.puts "madd #{arm64TACOperands(operands, :quad)}, xzr"
+            emitARM64Mul('mul', operands, :quad)
         when "subi"
             emitARM64TAC("sub", operands, :word)
         when "subp"

Modified: trunk/Source/_javascript_Core/offlineasm/instructions.rb (237626 => 237627)


--- trunk/Source/_javascript_Core/offlineasm/instructions.rb	2018-10-31 05:45:07 UTC (rev 237626)
+++ trunk/Source/_javascript_Core/offlineasm/instructions.rb	2018-10-31 06:14:04 UTC (rev 237627)
@@ -324,3 +324,7 @@
     instruction != "ret" and instruction != "jmp"
 end
 
+def isPowerOfTwo(value)
+    return false if value <= 0
+    (value & (value - 1)).zero?
+end

Modified: trunk/Source/_javascript_Core/offlineasm/x86.rb (237626 => 237627)


--- trunk/Source/_javascript_Core/offlineasm/x86.rb	2018-10-31 05:45:07 UTC (rev 237626)
+++ trunk/Source/_javascript_Core/offlineasm/x86.rb	2018-10-31 06:14:04 UTC (rev 237627)
@@ -798,11 +798,18 @@
     def handleX86Mul(kind)
         if operands.size == 3 and operands[0].is_a? Immediate
             $asm.puts "imul#{x86Suffix(kind)} #{x86Operands(kind, kind, kind)}"
-        else
-            # FIXME: could do some peephole in case the left operand is immediate and it's
-            # a power of two.
-            handleX86Op("imul#{x86Suffix(kind)}", kind)
+            return
         end
+
+        if operands.size == 2 and operands[0].is_a? Immediate
+            imm = operands[0].value
+            if imm > 0 and isPowerOfTwo(imm)
+                $asm.puts "sal#{x86Suffix(kind)} #{orderOperands(Immediate.new(nil, Math.log2(imm).to_i).x86Operand(kind), operands[1].x86Operand(kind))}"
+                return
+            end
+        end
+
+        handleX86Op("imul#{x86Suffix(kind)}", kind)
     end
     
     def handleX86Peek()
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to