Title: [288758] trunk
Revision
288758
Author
[email protected]
Date
2022-01-28 12:48:11 -0800 (Fri, 28 Jan 2022)

Log Message

[JSC] Add support for WASM branch hinting proposal
https://bugs.webkit.org/show_bug.cgi?id=235581

Patch by Tom Tartarin <[email protected]> on 2022-01-28
Reviewed by Yusuke Suzuki.

JSTests:

Add test for branch hinting custom section

* wasm.yaml:
* wasm/branch-hints/branchHintsModule.wasm: Added.
* wasm/branch-hints/branchHintsSection.js: Added.
(const.module):

Source/_javascript_Core:

See the proposal for a more detailed description: https://github.com/WebAssembly/branch-hinting.

This allows parsing a "code_annotation.branch_hint" custom section,
as per the code annotation proposal: https://github.com/WebAssembly/annotations.
This section provides per function information about how likely a branch at a
given offset is to be taken. It is similar to branch weight metadata in LLVM.

* _javascript_Core.xcodeproj/project.pbxproj:
* Sources.txt:
* runtime/OptionsList.h:
* wasm/WasmAirIRGenerator.cpp:
(JSC::Wasm::AirIRGenerator::addIf):
(JSC::Wasm::AirIRGenerator::addBranch):
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::addIf):
(JSC::Wasm::B3IRGenerator::addBranch):
* wasm/WasmBranchHints.h: Added.
(JSC::Wasm::BranchHintMap::add):
(JSC::Wasm::BranchHintMap::getBranchHint const):
(JSC::Wasm::BranchHintMap::isValidKey const):
(JSC::Wasm::isValidBranchHint):
* wasm/WasmBranchHintsSectionParser.cpp: Added.
(JSC::Wasm::BranchHintsSectionParser::parse):
* wasm/WasmBranchHintsSectionParser.h: Added.
(JSC::Wasm::BranchHintsSectionParser::BranchHintsSectionParser):
* wasm/WasmModuleInformation.h:
(JSC::Wasm::ModuleInformation::getBranchHint const):
* wasm/WasmSectionParser.cpp:
(JSC::Wasm::SectionParser::parseCustom):

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (288757 => 288758)


--- trunk/JSTests/ChangeLog	2022-01-28 20:19:33 UTC (rev 288757)
+++ trunk/JSTests/ChangeLog	2022-01-28 20:48:11 UTC (rev 288758)
@@ -1,3 +1,17 @@
+2022-01-28  Tom Tartarin  <[email protected]>
+
+        [JSC] Add support for WASM branch hinting proposal
+        https://bugs.webkit.org/show_bug.cgi?id=235581
+
+        Reviewed by Yusuke Suzuki.
+
+        Add test for branch hinting custom section
+
+        * wasm.yaml:
+        * wasm/branch-hints/branchHintsModule.wasm: Added.
+        * wasm/branch-hints/branchHintsSection.js: Added.
+        (const.module):
+
 2022-01-24  Yusuke Suzuki  <[email protected]>
 
         [JSC] Enable Array#groupBy and Array#groupByToMap

Added: trunk/JSTests/wasm/branch-hints/branchHintsModule.wasm (0 => 288758)


--- trunk/JSTests/wasm/branch-hints/branchHintsModule.wasm	                        (rev 0)
+++ trunk/JSTests/wasm/branch-hints/branchHintsModule.wasm	2022-01-28 20:48:11 UTC (rev 288758)
@@ -0,0 +1,4 @@
+��asm������+`����``����p\x80	A\x80\x80\xC0��memory��_main��	��A������%code_annotation.branch_hint��%
+1����+A��"!@ AІF@A! Aj"A\xA0\x8DG+�� 
\ No newline at end of file

Added: trunk/JSTests/wasm/branch-hints/branchHintsSection.js (0 => 288758)


--- trunk/JSTests/wasm/branch-hints/branchHintsSection.js	                        (rev 0)
+++ trunk/JSTests/wasm/branch-hints/branchHintsSection.js	2022-01-28 20:48:11 UTC (rev 288758)
@@ -0,0 +1,62 @@
+import * as assert from '../assert.js'
+
+/*
+This test loads a WebAssembly file compiled with wat2wasm with support for code annotations.
+see: https://github.com/yuri91/wabt/tree/annotations
+
+From the following .wat:
+(module
+  (type (;0;) (func))
+  (type (;1;) (func (param i32) (result i32)))
+  (type (;2;) (func (result i32)))
+  (func $__wasm_nullptr (type 0)
+    unreachable)
+  (func $main (type 2) (result i32)
+    (local i32 i32 i32 i32)
+    i32.const 0
+    local.tee 2
+    local.set 3
+    loop  ;; label = @1
+      local.get 2
+      i32.const 50000
+      i32.eq
+      (@code_annotation.branch_hint "\00") if  ;; label = @2
+        i32.const 1
+        local.set 3
+      end
+      local.get 2
+      i32.const 1
+      i32.add
+      local.tee 2
+      i32.const 100000
+      i32.ne
+      (@code_annotation.branch_hint "\01") br_if 0 (;@1;)
+    end
+    local.get 3)
+  (table (;0;) 1 1 funcref)
+  (memory (;0;) 17 128)
+  (global (;0;) (mut i32) (i32.const 1048576))
+  (export "memory" (memory 0))
+  (export "_main" (func $main))
+  (elem (;0;) (i32.const 0) func $__wasm_nullptr))
+*/
+
+const verbose = false;
+const wasmFile = 'branchHintsModule.wasm';
+
+const module = (location) => {
+    if (verbose)
+        print(`Processing ${location}`);
+    let buf = typeof readbuffer !== "undefined"? readbuffer(location) : read(location, 'binary');
+    if (verbose)
+        print(`  Size: ${buf.byteLength}`);
+    let module = new WebAssembly.Module(buf);
+    return module;
+};
+
+const branchHintsModule = module(wasmFile);
+const parsedBranchHintsSection = WebAssembly.Module.customSections(branchHintsModule, "code_annotation.branch_hint");
+assert.eq(parsedBranchHintsSection.length, 1);
+const instance = new WebAssembly.Instance(branchHintsModule);
+const result = instance.exports._main();
+assert.eq(result, 1);

Modified: trunk/JSTests/wasm.yaml (288757 => 288758)


--- trunk/JSTests/wasm.yaml	2022-01-28 20:19:33 UTC (rev 288757)
+++ trunk/JSTests/wasm.yaml	2022-01-28 20:48:11 UTC (rev 288758)
@@ -47,6 +47,8 @@
   cmd: runWebAssemblySuite unless parseRunCommands
 - path: wasm/v8/
   cmd: runWebAssemblySuite(:no_module, "mjsunit.js") unless parseRunCommands
+- path: wasm/branch-hints
+  cmd: runWebAssemblySuite("--useWebAssemblyBranchHints=true")
 
 - path: wasm/references-spec-tests/elem.wast.js
   cmd: runWebAssemblyReferenceSpecTest :normal

Modified: trunk/Source/_javascript_Core/ChangeLog (288757 => 288758)


--- trunk/Source/_javascript_Core/ChangeLog	2022-01-28 20:19:33 UTC (rev 288757)
+++ trunk/Source/_javascript_Core/ChangeLog	2022-01-28 20:48:11 UTC (rev 288758)
@@ -1,3 +1,41 @@
+2022-01-28  Tom Tartarin  <[email protected]>
+
+        [JSC] Add support for WASM branch hinting proposal
+        https://bugs.webkit.org/show_bug.cgi?id=235581
+
+        Reviewed by Yusuke Suzuki.
+
+        See the proposal for a more detailed description: https://github.com/WebAssembly/branch-hinting.
+
+        This allows parsing a "code_annotation.branch_hint" custom section,
+        as per the code annotation proposal: https://github.com/WebAssembly/annotations.
+        This section provides per function information about how likely a branch at a
+        given offset is to be taken. It is similar to branch weight metadata in LLVM.
+
+
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * Sources.txt:
+        * runtime/OptionsList.h:
+        * wasm/WasmAirIRGenerator.cpp:
+        (JSC::Wasm::AirIRGenerator::addIf):
+        (JSC::Wasm::AirIRGenerator::addBranch):
+        * wasm/WasmB3IRGenerator.cpp:
+        (JSC::Wasm::B3IRGenerator::addIf):
+        (JSC::Wasm::B3IRGenerator::addBranch):
+        * wasm/WasmBranchHints.h: Added.
+        (JSC::Wasm::BranchHintMap::add):
+        (JSC::Wasm::BranchHintMap::getBranchHint const):
+        (JSC::Wasm::BranchHintMap::isValidKey const):
+        (JSC::Wasm::isValidBranchHint):
+        * wasm/WasmBranchHintsSectionParser.cpp: Added.
+        (JSC::Wasm::BranchHintsSectionParser::parse):
+        * wasm/WasmBranchHintsSectionParser.h: Added.
+        (JSC::Wasm::BranchHintsSectionParser::BranchHintsSectionParser):
+        * wasm/WasmModuleInformation.h:
+        (JSC::Wasm::ModuleInformation::getBranchHint const):
+        * wasm/WasmSectionParser.cpp:
+        (JSC::Wasm::SectionParser::parseCustom):
+
 2022-01-28  Yusuke Suzuki  <[email protected]>
 
         [JSC] YarrJIT optimization for character BM search

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (288757 => 288758)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2022-01-28 20:19:33 UTC (rev 288757)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2022-01-28 20:48:11 UTC (rev 288758)
@@ -856,6 +856,8 @@
 		33A920BD23DA2C6D000EBAF0 /* CommonSlowPathsInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 33A920BC23DA2C6D000EBAF0 /* CommonSlowPathsInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		33B2A54722653481005A0F79 /* B3ValueInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84FB1BDACDAC0080FF74 /* B3ValueInlines.h */; };
 		33B2A548226543BF005A0F79 /* FTLLowerDFGToB3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEA0A04170513DB00BB722C /* FTLLowerDFGToB3.cpp */; };
+		37AAC093279F1BFC00D64842 /* WasmBranchHintsSectionParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 37AAC092279F124200D64842 /* WasmBranchHintsSectionParser.h */; };
+		37AAC094279F1C0500D64842 /* WasmBranchHints.h in Headers */ = {isa = PBXBuildFile; fileRef = 37AAC091279F124200D64842 /* WasmBranchHints.h */; };
 		37C738D21EDB56E4003F2B0B /* ParseInt.h in Headers */ = {isa = PBXBuildFile; fileRef = 37C738D11EDB5672003F2B0B /* ParseInt.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		412952771D2CF6BC00E78B89 /* builtins_generate_internals_wrapper_header.py in Headers */ = {isa = PBXBuildFile; fileRef = 412952731D2CF6AC00E78B89 /* builtins_generate_internals_wrapper_header.py */; settings = {ATTRIBUTES = (Private, ); }; };
 		412952781D2CF6BC00E78B89 /* builtins_generate_internals_wrapper_implementation.py in Headers */ = {isa = PBXBuildFile; fileRef = 412952741D2CF6AC00E78B89 /* builtins_generate_internals_wrapper_implementation.py */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -3726,6 +3728,9 @@
 		33B2A54522651D53005A0F79 /* MarkedSpace.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MarkedSpace.cpp; sourceTree = "<group>"; };
 		37119A7720CCB5DC002C6DC9 /* WebKitTargetConditionals.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = WebKitTargetConditionals.xcconfig; sourceTree = "<group>"; };
 		371D842C17C98B6E00ECF994 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
+		37AAC090279F124100D64842 /* WasmBranchHintsSectionParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmBranchHintsSectionParser.cpp; sourceTree = "<group>"; };
+		37AAC091279F124200D64842 /* WasmBranchHints.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = WasmBranchHints.h; sourceTree = "<group>"; };
+		37AAC092279F124200D64842 /* WasmBranchHintsSectionParser.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = WasmBranchHintsSectionParser.h; sourceTree = "<group>"; };
 		37C738D11EDB5672003F2B0B /* ParseInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParseInt.h; sourceTree = "<group>"; };
 		412952731D2CF6AC00E78B89 /* builtins_generate_internals_wrapper_header.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = builtins_generate_internals_wrapper_header.py; sourceTree = "<group>"; };
 		412952741D2CF6AC00E78B89 /* builtins_generate_internals_wrapper_implementation.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = builtins_generate_internals_wrapper_implementation.py; sourceTree = "<group>"; };
@@ -7309,6 +7314,9 @@
 		7B98D1331B60CD1E0023B1A4 /* wasm */ = {
 			isa = PBXGroup;
 			children = (
+				37AAC091279F124200D64842 /* WasmBranchHints.h */,
+				37AAC090279F124100D64842 /* WasmBranchHintsSectionParser.cpp */,
+				37AAC092279F124200D64842 /* WasmBranchHintsSectionParser.h */,
 				AD2FCB8A1DB5840000B3E736 /* js */,
 				52847AD921FFB8630061A9DB /* WasmAirIRGenerator.cpp */,
 				52847ADA21FFB8630061A9DB /* WasmAirIRGenerator.h */,
@@ -10956,6 +10964,7 @@
 				0FE050291AA9095600D33B33 /* ScopedArgumentsTable.h in Headers */,
 				0FE0502B1AA9095600D33B33 /* ScopeOffset.h in Headers */,
 				0F24E55217EE274900ABB217 /* ScratchRegisterAllocator.h in Headers */,
+				37AAC094279F1C0500D64842 /* WasmBranchHints.h in Headers */,
 				33111B8B2397256500AA34CE /* Scribble.h in Headers */,
 				A5FD0068189AFE9C00633231 /* ScriptArguments.h in Headers */,
 				A5FD006E189B00AA00633231 /* ScriptCallFrame.h in Headers */,
@@ -11082,6 +11091,7 @@
 				FE3422121D6B81C30032BE88 /* ThrowScope.h in Headers */,
 				0F572D4F16879FDD00E57FBD /* ThunkGenerator.h in Headers */,
 				A7386556118697B400540279 /* ThunkGenerators.h in Headers */,
+				37AAC093279F1BFC00D64842 /* WasmBranchHintsSectionParser.h in Headers */,
 				141448CD13A1783700F5BA1A /* TinyBloomFilter.h in Headers */,
 				0F55989817C86C5800A1E543 /* ToNativeFromValue.h in Headers */,
 				0F2D4DE919832DAC007D4B19 /* ToThisStatus.h in Headers */,

Modified: trunk/Source/_javascript_Core/Sources.txt (288757 => 288758)


--- trunk/Source/_javascript_Core/Sources.txt	2022-01-28 20:19:33 UTC (rev 288757)
+++ trunk/Source/_javascript_Core/Sources.txt	2022-01-28 20:48:11 UTC (rev 288758)
@@ -1065,6 +1065,7 @@
 wasm/WasmB3IRGenerator.cpp
 wasm/WasmBBQPlan.cpp
 wasm/WasmBinding.cpp
+wasm/WasmBranchHintsSectionParser.cpp
 wasm/WasmCallee.cpp
 wasm/WasmCalleeGroup.cpp
 wasm/WasmCalleeRegistry.cpp

Modified: trunk/Source/_javascript_Core/runtime/OptionsList.h (288757 => 288758)


--- trunk/Source/_javascript_Core/runtime/OptionsList.h	2022-01-28 20:19:33 UTC (rev 288757)
+++ trunk/Source/_javascript_Core/runtime/OptionsList.h	2022-01-28 20:48:11 UTC (rev 288758)
@@ -550,6 +550,7 @@
     v(Bool, useWebAssemblyThreading, true, Normal, "Allow instructions from the wasm threading spec.") \
     v(Bool, useWebAssemblyTypedFunctionReferences, false, Normal, "Allow function types from the wasm typed function references spec.") \
     v(Bool, useWebAssemblyExceptions, true, Normal, "Allow the new section and instructions from the wasm exception handling spec.") \
+    v(Bool, useWebAssemblyBranchHints, false, Normal, "Allow the new section from the wasm branch hinting spec.") \
 
 
 enum OptionEquivalence {

Modified: trunk/Source/_javascript_Core/wasm/WasmAirIRGenerator.cpp (288757 => 288758)


--- trunk/Source/_javascript_Core/wasm/WasmAirIRGenerator.cpp	2022-01-28 20:19:33 UTC (rev 288757)
+++ trunk/Source/_javascript_Core/wasm/WasmAirIRGenerator.cpp	2022-01-28 20:48:11 UTC (rev 288758)
@@ -44,6 +44,7 @@
 #include "JSCJSValueInlines.h"
 #include "JSWebAssemblyInstance.h"
 #include "ScratchRegisterAllocator.h"
+#include "WasmBranchHints.h"
 #include "WasmCallingConvention.h"
 #include "WasmContextInlines.h"
 #include "WasmExceptionType.h"
@@ -3174,10 +3175,27 @@
     BasicBlock* taken = m_code.addBlock();
     BasicBlock* notTaken = m_code.addBlock();
     BasicBlock* continuation = m_code.addBlock();
-    
+    B3::FrequencyClass takenFrequency = B3::FrequencyClass::Normal;
+    B3::FrequencyClass notTakenFrequency= B3::FrequencyClass::Normal;
+
+    if (Options::useWebAssemblyBranchHints()) {
+        BranchHint hint = m_info.getBranchHint(m_functionIndex, m_parser->currentOpcodeStartingOffset());
+
+        switch (hint) {
+        case BranchHint::Unlikely:
+            takenFrequency = B3::FrequencyClass::Rare;
+            break;
+        case BranchHint::Likely:
+            notTakenFrequency = B3::FrequencyClass::Rare;
+            break;
+        case BranchHint::Invalid:
+            break;
+        }
+    }
+
     // Wasm bools are i32.
     append(BranchTest32, Arg::resCond(MacroAssembler::NonZero), condition, condition);
-    m_currentBlock->setSuccessors(taken, notTaken);
+    m_currentBlock->setSuccessors(FrequentedBlock(taken, takenFrequency), FrequentedBlock(notTaken, notTakenFrequency));
 
     m_currentBlock = taken;
     splitStack(signature, enclosingStack, newStack);
@@ -3417,14 +3435,32 @@
     unifyValuesWithBlock(returnValues, data.results);
 
     BasicBlock* target = data.targetBlockForBranch();
+    B3::FrequencyClass targetFrequency = B3::FrequencyClass::Normal;
+    B3::FrequencyClass continuationFrequency = B3::FrequencyClass::Normal;
+
+    if (Options::useWebAssemblyBranchHints()) {
+        BranchHint hint = m_info.getBranchHint(m_functionIndex, m_parser->currentOpcodeStartingOffset());
+
+        switch (hint) {
+        case BranchHint::Unlikely:
+            targetFrequency = B3::FrequencyClass::Rare;
+            break;
+        case BranchHint::Likely:
+            continuationFrequency = B3::FrequencyClass::Rare;
+            break;
+        case BranchHint::Invalid:
+            break;
+        }
+    }
+
     if (condition) {
         BasicBlock* continuation = m_code.addBlock();
         append(BranchTest32, Arg::resCond(MacroAssembler::NonZero), condition, condition);
-        m_currentBlock->setSuccessors(target, continuation);
+        m_currentBlock->setSuccessors(FrequentedBlock(target, targetFrequency), FrequentedBlock(continuation, continuationFrequency));
         m_currentBlock = continuation;
     } else {
         append(Jump);
-        m_currentBlock->setSuccessors(target);
+        m_currentBlock->setSuccessors(FrequentedBlock(target, targetFrequency));
     }
 
     return { };

Modified: trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp (288757 => 288758)


--- trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp	2022-01-28 20:19:33 UTC (rev 288757)
+++ trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp	2022-01-28 20:48:11 UTC (rev 288758)
@@ -52,7 +52,7 @@
 #include "JSWebAssemblyInstance.h"
 #include "ProbeContext.h"
 #include "ScratchRegisterAllocator.h"
-#include "ScratchRegisterAllocator.h"
+#include "WasmBranchHints.h"
 #include "WasmCallingConvention.h"
 #include "WasmContextInlines.h"
 #include "WasmExceptionType.h"
@@ -2475,9 +2475,26 @@
     BasicBlock* taken = m_proc.addBlock();
     BasicBlock* notTaken = m_proc.addBlock();
     BasicBlock* continuation = m_proc.addBlock();
+    FrequencyClass takenFrequency = FrequencyClass::Normal;
+    FrequencyClass notTakenFrequency = FrequencyClass::Normal;
 
+    if (Options::useWebAssemblyBranchHints()) {
+        BranchHint hint = m_info.getBranchHint(m_functionIndex, m_parser->currentOpcodeStartingOffset());
+
+        switch (hint) {
+        case BranchHint::Unlikely:
+            takenFrequency = FrequencyClass::Rare;
+            break;
+        case BranchHint::Likely:
+            notTakenFrequency = FrequencyClass::Rare;
+            break;
+        case BranchHint::Invalid:
+            break;
+        }
+    }
+
     m_currentBlock->appendNew<Value>(m_proc, B3::Branch, origin(), get(condition));
-    m_currentBlock->setSuccessors(FrequentedBlock(taken), FrequentedBlock(notTaken));
+    m_currentBlock->setSuccessors(FrequentedBlock(taken, takenFrequency), FrequentedBlock(notTaken, notTakenFrequency));
     taken->addPredecessor(m_currentBlock);
     notTaken->addPredecessor(m_currentBlock);
 
@@ -2721,15 +2738,33 @@
     unifyValuesWithBlock(returnValues, data);
 
     BasicBlock* target = data.targetBlockForBranch();
+    FrequencyClass targetFrequency = FrequencyClass::Normal;
+    FrequencyClass continuationFrequency = FrequencyClass::Normal;
+
+    if (Options::useWebAssemblyBranchHints()) {
+        BranchHint hint = m_info.getBranchHint(m_functionIndex, m_parser->currentOpcodeStartingOffset());
+
+        switch (hint) {
+        case BranchHint::Unlikely:
+            targetFrequency = FrequencyClass::Rare;
+            break;
+        case BranchHint::Likely:
+            continuationFrequency = FrequencyClass::Rare;
+            break;
+        case BranchHint::Invalid:
+            break;
+        }
+    }
+
     if (condition) {
         BasicBlock* continuation = m_proc.addBlock();
         m_currentBlock->appendNew<Value>(m_proc, B3::Branch, origin(), get(condition));
-        m_currentBlock->setSuccessors(FrequentedBlock(target), FrequentedBlock(continuation));
+        m_currentBlock->setSuccessors(FrequentedBlock(target, targetFrequency), FrequentedBlock(continuation, continuationFrequency));
         target->addPredecessor(m_currentBlock);
         continuation->addPredecessor(m_currentBlock);
         m_currentBlock = continuation;
     } else {
-        m_currentBlock->appendNewControlValue(m_proc, Jump, origin(), FrequentedBlock(target));
+        m_currentBlock->appendNewControlValue(m_proc, Jump, origin(), FrequentedBlock(target, targetFrequency));
         target->addPredecessor(m_currentBlock);
     }
 

Added: trunk/Source/_javascript_Core/wasm/WasmBranchHints.h (0 => 288758)


--- trunk/Source/_javascript_Core/wasm/WasmBranchHints.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/wasm/WasmBranchHints.h	2022-01-28 20:48:11 UTC (rev 288758)
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2022 Leaning Technologies Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/HashMap.h>
+
+namespace JSC {
+namespace Wasm {
+
+enum class BranchHint : uint8_t {
+    Unlikely,
+    Likely,
+    Invalid,
+};
+
+class BranchHintMap {
+
+public:
+
+    void add(uint32_t branchOffset, BranchHint hint)
+    {
+        m_map.add(branchOffset, hint);
+    }
+
+    BranchHint getBranchHint(uint32_t branchOffset) const
+    {
+        auto it = m_map.find(branchOffset);
+        if (it == m_map.end())
+            return BranchHint::Invalid;
+        return it->value;
+    }
+
+    bool isValidKey(uint32_t branchOffset) const
+    {
+        return m_map.isValidKey(branchOffset);
+    }
+
+private:
+
+    HashMap<uint32_t, BranchHint, IntHash<uint32_t>, WTF::UnsignedWithZeroKeyHashTraits<uint32_t>> m_map;
+
+};
+
+inline constexpr bool isValidBranchHint(BranchHint hint)
+{
+    switch (hint) {
+    case BranchHint::Likely:
+    case BranchHint::Unlikely:
+        return true;
+    default:
+        return false;
+    }
+    return false;
+}
+
+}
+} // namespace JSC::Wasm

Added: trunk/Source/_javascript_Core/wasm/WasmBranchHintsSectionParser.cpp (0 => 288758)


--- trunk/Source/_javascript_Core/wasm/WasmBranchHintsSectionParser.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/wasm/WasmBranchHintsSectionParser.cpp	2022-01-28 20:48:11 UTC (rev 288758)
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2022 Leaning Technologies Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if ENABLE(WEBASSEMBLY)
+
+#include "config.h"
+#include "WasmBranchHintsSectionParser.h"
+
+namespace JSC {
+namespace Wasm {
+
+auto BranchHintsSectionParser::parse() -> PartialResult
+{
+    uint32_t functionCount;
+    int64_t previousFunctionIndex = -1;
+    WASM_PARSER_FAIL_IF(!parseVarUInt32(functionCount), "can't get function count");
+
+    for (uint32_t i = 0; i < functionCount; ++i) {
+        uint32_t functionIndex;
+        uint32_t hintCount;
+        WASM_PARSER_FAIL_IF(!parseVarUInt32(functionIndex), "can't get function index for function ", i);
+        WASM_PARSER_FAIL_IF(static_cast<int64_t>(functionIndex) < previousFunctionIndex, "invalid function index ", functionIndex, " for function ", i);
+
+        previousFunctionIndex = functionIndex;
+
+        WASM_PARSER_FAIL_IF(!parseVarUInt32(hintCount), "can't get number of hints for function ", i);
+
+        if (!hintCount)
+            continue;
+
+        int64_t previousBranchOffset = -1;
+        BranchHintMap branchHintsForFunction;
+        for (uint32_t j = 0; j < hintCount; ++j) {
+            uint32_t branchOffset;
+            WASM_PARSER_FAIL_IF(!parseVarUInt32(branchOffset), "can't get branch offset for hint ", j);
+            WASM_PARSER_FAIL_IF(static_cast<int64_t>(branchOffset) < previousBranchOffset
+                || !m_info->branchHints.isValidKey(branchOffset), "invalid branch offset ", branchOffset, " for hint ", j);
+
+            previousBranchOffset = branchOffset;
+
+            uint8_t reservedByte;
+            WASM_PARSER_FAIL_IF(!parseVarUInt1(reservedByte), "can't get reserved byte for hint ", j);
+            WASM_PARSER_FAIL_IF(reservedByte != 0x1, "invalid reserved byte for hint ", j);
+
+            uint8_t parsedBranchHint;
+            WASM_PARSER_FAIL_IF(!parseVarUInt1(parsedBranchHint), "can't get or invalid branch hint value for hint ", j);
+
+            BranchHint branchHint = static_cast<BranchHint>(parsedBranchHint);
+            ASSERT(isValidBranchHint(branchHint));
+
+            branchHintsForFunction.add(branchOffset, branchHint);
+        }
+        m_info->branchHints.add(functionIndex, WTFMove(branchHintsForFunction));
+    }
+    return { };
+}
+
+}
+} // namespace JSC::Wasm
+
+#endif // ENABLE(WEBASSEMBLY)

Added: trunk/Source/_javascript_Core/wasm/WasmBranchHintsSectionParser.h (0 => 288758)


--- trunk/Source/_javascript_Core/wasm/WasmBranchHintsSectionParser.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/wasm/WasmBranchHintsSectionParser.h	2022-01-28 20:48:11 UTC (rev 288758)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 Leaning Technologies Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEBASSEMBLY)
+
+#include "WasmParser.h"
+
+namespace JSC {
+namespace Wasm {
+
+class BranchHintsSectionParser : public Parser<void> {
+public:
+    BranchHintsSectionParser(const uint8_t* sourceBuffer, size_t sourceLength, ModuleInformation& info)
+        : Parser(sourceBuffer, sourceLength)
+        , m_info(info)
+    {
+    }
+    PartialResult parse();
+
+private:
+    Ref<ModuleInformation> m_info;
+};
+
+}
+} // namespace JSC::Wasm
+
+#endif // ENABLE(WEBASSEMBLY)

Modified: trunk/Source/_javascript_Core/wasm/WasmModuleInformation.h (288757 => 288758)


--- trunk/Source/_javascript_Core/wasm/WasmModuleInformation.h	2022-01-28 20:19:33 UTC (rev 288757)
+++ trunk/Source/_javascript_Core/wasm/WasmModuleInformation.h	2022-01-28 20:48:11 UTC (rev 288758)
@@ -27,13 +27,18 @@
 
 #if ENABLE(WEBASSEMBLY)
 
+#include "WasmBranchHints.h"
 #include "WasmFormat.h"
 
 #include <wtf/BitVector.h>
+#include <wtf/HashMap.h>
 
 namespace JSC { namespace Wasm {
 
 struct ModuleInformation : public ThreadSafeRefCounted<ModuleInformation> {
+
+    using BranchHints = HashMap<uint32_t, BranchHintMap, IntHash<uint32_t>, WTF::UnsignedWithZeroKeyHashTraits<uint32_t>>;
+
     ModuleInformation();
     ModuleInformation(const ModuleInformation&) = delete;
     ModuleInformation(ModuleInformation&&) = delete;
@@ -96,6 +101,14 @@
 
     bool hasMemoryImport() const { return memory.isImport(); }
 
+    BranchHint getBranchHint(uint32_t functionOffset, uint32_t branchOffset) const
+    {
+        auto it = branchHints.find(functionOffset);
+        return it == branchHints.end()
+            ? BranchHint::Invalid
+            : it->value.getBranchHint(branchOffset);
+    }
+
     Vector<Import> imports;
     Vector<SignatureIndex> importFunctionSignatureIndices;
     Vector<SignatureIndex> internalFunctionSignatureIndices;
@@ -117,6 +130,7 @@
     uint32_t codeSectionSize { 0 };
     Vector<CustomSection> customSections;
     Ref<NameSection> nameSection;
+    BranchHints branchHints;
     uint32_t numberOfDataSegments { 0 };
 
     BitVector m_declaredFunctions;

Modified: trunk/Source/_javascript_Core/wasm/WasmSectionParser.cpp (288757 => 288758)


--- trunk/Source/_javascript_Core/wasm/WasmSectionParser.cpp	2022-01-28 20:19:33 UTC (rev 288757)
+++ trunk/Source/_javascript_Core/wasm/WasmSectionParser.cpp	2022-01-28 20:48:11 UTC (rev 288758)
@@ -30,6 +30,7 @@
 #if ENABLE(WEBASSEMBLY)
 
 #include "JSCJSValueInlines.h"
+#include "WasmBranchHintsSectionParser.h"
 #include "WasmMemoryInformation.h"
 #include "WasmNameSectionParser.h"
 #include "WasmOps.h"
@@ -896,6 +897,12 @@
         NameSectionParser nameSectionParser(section.payload.begin(), section.payload.size(), m_info);
         if (auto nameSection = nameSectionParser.parse())
             m_info->nameSection = WTFMove(*nameSection);
+    } else if (Options::useWebAssemblyBranchHints()) {
+        Name branchHintsName = { 'c', 'o', 'd', 'e', '_', 'a', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', '.', 'b', 'r', 'a', 'n', 'c', 'h', '_', 'h', 'i', 'n', 't' };
+        if (section.name == branchHintsName) {
+            BranchHintsSectionParser branchHintsSectionParser(section.payload.begin(), section.payload.size(), m_info);
+            branchHintsSectionParser.parse();
+        }
     }
 
     m_info->customSections.uncheckedAppend(WTFMove(section));
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to