Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (286789 => 286790)
--- trunk/Source/_javascript_Core/ChangeLog 2021-12-09 19:01:10 UTC (rev 286789)
+++ trunk/Source/_javascript_Core/ChangeLog 2021-12-09 19:07:58 UTC (rev 286790)
@@ -1,3 +1,42 @@
+2021-12-09 Saam Barati <[email protected]>
+
+ Add an option to dump the B3 IR for an allowlist of Wasm function indices
+ https://bugs.webkit.org/show_bug.cgi?id=234028
+
+ Reviewed by Tadeu Zagallo.
+
+ * b3/B3Common.cpp:
+ (JSC::B3::shouldDumpIR):
+ * b3/B3Common.h:
+ * b3/B3Generate.cpp:
+ (JSC::B3::generateToAir):
+ * b3/B3Procedure.cpp:
+ (JSC::B3::Procedure::dump const):
+ (JSC::B3::Procedure::setShouldDumpIR):
+ * b3/B3Procedure.h:
+ (JSC::B3::Procedure::shouldDumpIR const):
+ * b3/air/AirGenerate.cpp:
+ (JSC::B3::Air::prepareForGeneration):
+ * b3/testb3.h:
+ (shouldBeVerbose):
+ (lowerToAirForTesting):
+ * b3/testb3_6.cpp:
+ (testInterpreter):
+ (testMoveConstants):
+ * b3/testb3_7.cpp:
+ (testReduceStrengthReassociation):
+ * runtime/OptionsList.h:
+ * tools/FunctionAllowlist.cpp:
+ (JSC::FunctionAllowlist::shouldDumpWasmFunction const):
+ * tools/FunctionAllowlist.h:
+ * wasm/WasmB3IRGenerator.cpp:
+ (JSC::Wasm::shouldDumpIRFor):
+ (JSC::Wasm::parseAndCompile):
+ * wasm/WasmOMGForOSREntryPlan.cpp:
+ (JSC::Wasm::OMGForOSREntryPlan::work):
+ * wasm/WasmOMGPlan.cpp:
+ (JSC::Wasm::OMGPlan::work):
+
2021-12-09 Yusuke Suzuki <[email protected]>
[JSC] Introduce BaselineCallLinkInfo and OptimizingCallLinkInfo to shrink sizeof(BaselineCallLinkInfo)
Modified: trunk/Source/_javascript_Core/b3/B3Common.cpp (286789 => 286790)
--- trunk/Source/_javascript_Core/b3/B3Common.cpp 2021-12-09 19:01:10 UTC (rev 286789)
+++ trunk/Source/_javascript_Core/b3/B3Common.cpp 2021-12-09 19:07:58 UTC (rev 286790)
@@ -36,8 +36,11 @@
const char* const tierName = "b3 ";
-bool shouldDumpIR(B3CompilationMode mode)
+bool shouldDumpIR(Procedure& procedure, B3CompilationMode mode)
{
+ if (procedure.shouldDumpIR())
+ return true;
+
#if ENABLE(FTL_JIT)
return FTL::verboseCompilationEnabled() || FTL::shouldDumpDisassembly() || shouldDumpIRAtEachPhase(mode);
#else
Modified: trunk/Source/_javascript_Core/b3/B3Common.h (286789 => 286790)
--- trunk/Source/_javascript_Core/b3/B3Common.h 2021-12-09 19:01:10 UTC (rev 286789)
+++ trunk/Source/_javascript_Core/b3/B3Common.h 2021-12-09 19:07:58 UTC (rev 286790)
@@ -34,6 +34,8 @@
namespace JSC { namespace B3 {
+class Procedure;
+
extern const char* const tierName;
enum B3CompilationMode {
@@ -41,7 +43,7 @@
AirMode
};
-JS_EXPORT_PRIVATE bool shouldDumpIR(B3CompilationMode);
+JS_EXPORT_PRIVATE bool shouldDumpIR(Procedure&, B3CompilationMode);
bool shouldDumpIRAtEachPhase(B3CompilationMode);
bool shouldValidateIR();
bool shouldValidateIRAtEachPhase();
Modified: trunk/Source/_javascript_Core/b3/B3Generate.cpp (286789 => 286790)
--- trunk/Source/_javascript_Core/b3/B3Generate.cpp 2021-12-09 19:01:10 UTC (rev 286789)
+++ trunk/Source/_javascript_Core/b3/B3Generate.cpp 2021-12-09 19:07:58 UTC (rev 286790)
@@ -70,7 +70,7 @@
{
TimingScope timingScope("generateToAir");
- if (shouldDumpIR(B3Mode) && !shouldDumpIRAtEachPhase(B3Mode)) {
+ if (shouldDumpIR(procedure, B3Mode) && !shouldDumpIRAtEachPhase(B3Mode)) {
dataLog(tierName, "Initial B3:\n");
dataLog(procedure);
}
@@ -130,7 +130,7 @@
// If we're doing super verbose dumping, the phase scope of any phase will already do a dump.
// Note that lowerToAir() acts like a phase in this regard.
- if (shouldDumpIR(B3Mode) && !shouldDumpIRAtEachPhase(B3Mode)) {
+ if (shouldDumpIR(procedure, B3Mode) && !shouldDumpIRAtEachPhase(B3Mode)) {
dataLog("B3 after ", procedure.lastPhaseName(), ", before generation:\n");
dataLog(procedure);
}
Modified: trunk/Source/_javascript_Core/b3/B3Procedure.cpp (286789 => 286790)
--- trunk/Source/_javascript_Core/b3/B3Procedure.cpp 2021-12-09 19:01:10 UTC (rev 286789)
+++ trunk/Source/_javascript_Core/b3/B3Procedure.cpp 2021-12-09 19:07:58 UTC (rev 286790)
@@ -228,6 +228,7 @@
void Procedure::dump(PrintStream& out) const
{
+ out.print("Opt Level: ", optLevel(), "\n");
IndexSet<Value*> valuesInBlocks;
for (BasicBlock* block : *this) {
out.print(deepDump(*this, block));
@@ -479,6 +480,12 @@
m_values.packIndices();
}
+void Procedure::setShouldDumpIR()
+{
+ m_shouldDumpIR = true;
+ m_code->forcePreservationOfB3Origins();
+}
+
} } // namespace JSC::B3
#endif // ENABLE(B3_JIT)
Modified: trunk/Source/_javascript_Core/b3/B3Procedure.h (286789 => 286790)
--- trunk/Source/_javascript_Core/b3/B3Procedure.h 2021-12-09 19:01:10 UTC (rev 286789)
+++ trunk/Source/_javascript_Core/b3/B3Procedure.h 2021-12-09 19:07:58 UTC (rev 286790)
@@ -280,6 +280,9 @@
JS_EXPORT_PRIVATE void freeUnneededB3ValuesAfterLowering();
+ bool shouldDumpIR() const { return m_shouldDumpIR; }
+ void setShouldDumpIR();
+
private:
friend class BlockInsertionSet;
@@ -307,6 +310,7 @@
bool m_needsUsedRegisters { true };
bool m_hasQuirks { false };
bool m_needsPCToOriginMap { false };
+ bool m_shouldDumpIR { false };
};
} } // namespace JSC::B3
Modified: trunk/Source/_javascript_Core/b3/air/AirGenerate.cpp (286789 => 286790)
--- trunk/Source/_javascript_Core/b3/air/AirGenerate.cpp 2021-12-09 19:01:10 UTC (rev 286789)
+++ trunk/Source/_javascript_Core/b3/air/AirGenerate.cpp 2021-12-09 19:07:58 UTC (rev 286790)
@@ -61,7 +61,7 @@
TimingScope timingScope("Air::prepareForGeneration");
// If we're doing super verbose dumping, the phase scope of any phase will already do a dump.
- if (shouldDumpIR(AirMode) && !shouldDumpIRAtEachPhase(AirMode)) {
+ if (shouldDumpIR(code.proc(), AirMode) && !shouldDumpIRAtEachPhase(AirMode)) {
dataLog(tierName, "Initial air:\n");
dataLog(code);
}
@@ -89,7 +89,7 @@
if (shouldValidateIR())
validate(code);
- if (shouldDumpIR(AirMode)) {
+ if (shouldDumpIR(code.proc(), AirMode)) {
dataLog("Air after ", code.lastPhaseName(), ", before generation:\n");
dataLog(code);
}
@@ -183,7 +183,7 @@
// Do a final dump of Air. Note that we have to do this even if we are doing per-phase dumping,
// since the final generation is not a phase.
- if (shouldDumpIR(AirMode)) {
+ if (shouldDumpIR(code.proc(), AirMode)) {
dataLog("Air after ", code.lastPhaseName(), ", before generation:\n");
dataLog(code);
}
Modified: trunk/Source/_javascript_Core/b3/testb3.h (286789 => 286790)
--- trunk/Source/_javascript_Core/b3/testb3.h 2021-12-09 19:01:10 UTC (rev 286789)
+++ trunk/Source/_javascript_Core/b3/testb3.h 2021-12-09 19:07:58 UTC (rev 286790)
@@ -97,9 +97,9 @@
using namespace JSC;
using namespace JSC::B3;
-inline bool shouldBeVerbose()
+inline bool shouldBeVerbose(Procedure& procedure)
{
- return shouldDumpIR(B3Mode);
+ return shouldDumpIR(procedure, B3Mode);
}
extern Lock crashLock;
@@ -220,13 +220,13 @@
{
proc.resetReachability();
- if (shouldBeVerbose())
+ if (shouldBeVerbose(proc))
dataLog("B3 before lowering:\n", proc);
validate(proc);
lowerToAir(proc);
- if (shouldBeVerbose())
+ if (shouldBeVerbose(proc))
dataLog("Air after lowering:\n", proc.code());
Air::validate(proc.code());
Modified: trunk/Source/_javascript_Core/b3/testb3_6.cpp (286789 => 286790)
--- trunk/Source/_javascript_Core/b3/testb3_6.cpp 2021-12-09 19:01:10 UTC (rev 286789)
+++ trunk/Source/_javascript_Core/b3/testb3_6.cpp 2021-12-09 19:07:58 UTC (rev 286790)
@@ -1796,7 +1796,7 @@
data.append(1);
data.append(0);
- if (shouldBeVerbose())
+ if (shouldBeVerbose(proc))
dataLog("data = "" listDump(data), "\n");
// We'll write a program that prints the numbers 1..100.
@@ -1832,7 +1832,7 @@
code.append(Stop);
- if (shouldBeVerbose())
+ if (shouldBeVerbose(proc))
dataLog("code = ", listDump(code), "\n");
CHECK(!invoke<intptr_t>(*interpreter, data.data(), code.data(), &stream));
@@ -1841,7 +1841,7 @@
for (unsigned i = 0; i < 100; ++i)
CHECK(stream[i] == i + 1);
- if (shouldBeVerbose())
+ if (shouldBeVerbose(proc))
dataLog("stream = ", listDump(stream), "\n");
}
@@ -2783,7 +2783,7 @@
auto check = [] (Procedure& proc) {
proc.resetReachability();
- if (shouldBeVerbose()) {
+ if (shouldBeVerbose(proc)) {
dataLog("IR before:\n");
dataLog(proc);
}
@@ -2790,7 +2790,7 @@
moveConstants(proc);
- if (shouldBeVerbose()) {
+ if (shouldBeVerbose(proc)) {
dataLog("IR after:\n");
dataLog(proc);
}
Modified: trunk/Source/_javascript_Core/b3/testb3_7.cpp (286789 => 286790)
--- trunk/Source/_javascript_Core/b3/testb3_7.cpp 2021-12-09 19:01:10 UTC (rev 286789)
+++ trunk/Source/_javascript_Core/b3/testb3_7.cpp 2021-12-09 19:07:58 UTC (rev 286790)
@@ -359,7 +359,7 @@
proc.resetReachability();
- if (shouldBeVerbose()) {
+ if (shouldBeVerbose(proc)) {
dataLog("IR before reduceStrength:\n");
dataLog(proc);
}
@@ -366,7 +366,7 @@
reduceStrength(proc);
- if (shouldBeVerbose()) {
+ if (shouldBeVerbose(proc)) {
dataLog("IR after reduceStrength:\n");
dataLog(proc);
}
Modified: trunk/Source/_javascript_Core/runtime/OptionsList.h (286789 => 286790)
--- trunk/Source/_javascript_Core/runtime/OptionsList.h 2021-12-09 19:01:10 UTC (rev 286789)
+++ trunk/Source/_javascript_Core/runtime/OptionsList.h 2021-12-09 19:07:58 UTC (rev 286790)
@@ -133,6 +133,7 @@
v(Bool, dumpFTLDisassembly, false, Normal, "dumps disassembly of FTL function upon compilation") \
v(Bool, dumpRegExpDisassembly, false, Normal, "dumps disassembly of RegExp upon compilation") \
v(Bool, dumpWasmDisassembly, false, Normal, "dumps disassembly of all Wasm code upon compilation") \
+ v(OptionString, wasmB3FunctionsToDump, nullptr, Normal, "file with newline separated list of function indices to dump IR/disassembly for, if no such file exists, the function index itself") \
v(Bool, dumpBBQDisassembly, false, Normal, "dumps disassembly of BBQ Wasm code upon compilation") \
v(Bool, dumpOMGDisassembly, false, Normal, "dumps disassembly of OMG Wasm code upon compilation") \
v(Bool, logJITCodeForPerf, false, Configurable, nullptr) \
Modified: trunk/Source/_javascript_Core/tools/FunctionAllowlist.cpp (286789 => 286790)
--- trunk/Source/_javascript_Core/tools/FunctionAllowlist.cpp 2021-12-09 19:01:10 UTC (rev 286789)
+++ trunk/Source/_javascript_Core/tools/FunctionAllowlist.cpp 2021-12-09 19:07:58 UTC (rev 286790)
@@ -96,6 +96,15 @@
return m_entries.contains(name + '#' + hash);
}
+bool FunctionAllowlist::shouldDumpWasmFunction(uint32_t index) const
+{
+ if (!m_hasActiveAllowlist)
+ return false;
+ if (m_entries.isEmpty())
+ return false;
+ return m_entries.contains(String::number(index));
+}
+
} // namespace JSC
#endif // ENABLE(JIT)
Modified: trunk/Source/_javascript_Core/tools/FunctionAllowlist.h (286789 => 286790)
--- trunk/Source/_javascript_Core/tools/FunctionAllowlist.h 2021-12-09 19:01:10 UTC (rev 286789)
+++ trunk/Source/_javascript_Core/tools/FunctionAllowlist.h 2021-12-09 19:07:58 UTC (rev 286790)
@@ -37,6 +37,7 @@
explicit FunctionAllowlist(const char*);
bool contains(CodeBlock*) const;
+ bool shouldDumpWasmFunction(uint32_t) const;
private:
HashSet<String> m_entries;
Modified: trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp (286789 => 286790)
--- trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp 2021-12-09 19:01:10 UTC (rev 286789)
+++ trunk/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp 2021-12-09 19:07:58 UTC (rev 286790)
@@ -46,6 +46,7 @@
#include "B3VariableValue.h"
#include "B3WasmAddressValue.h"
#include "B3WasmBoundsCheckValue.h"
+#include "FunctionAllowlist.h"
#include "JSCJSValueInlines.h"
#include "JSWebAssemblyInstance.h"
#include "ProbeContext.h"
@@ -3228,6 +3229,17 @@
return bitwise_cast<Origin>(origin);
}
+static bool shouldDumpIRFor(uint32_t functionIndex)
+{
+ static LazyNeverDestroyed<FunctionAllowlist> dumpAllowlist;
+ static std::once_flag initializeAllowlistFlag;
+ std::call_once(initializeAllowlistFlag, [] {
+ const char* functionAllowlistFile = Options::wasmB3FunctionsToDump();
+ dumpAllowlist.construct(functionAllowlistFile);
+ });
+ return dumpAllowlist->shouldDumpWasmFunction(functionIndex);
+}
+
Expected<std::unique_ptr<InternalFunction>, String> parseAndCompile(CompilationContext& compilationContext, const FunctionData& function, const Signature& signature, Vector<UnlinkedWasmToWasmCall>& unlinkedWasmToWasmCalls, unsigned& osrEntryScratchBufferSize, const ModuleInformation& info, MemoryMode mode, CompilationMode compilationMode, uint32_t functionIndex, uint32_t loopIndexForOSREntry, TierUpCount* tierUp)
{
auto result = makeUnique<InternalFunction>();
@@ -3237,6 +3249,8 @@
compilationContext.procedure = makeUnique<Procedure>();
Procedure& procedure = *compilationContext.procedure;
+ if (shouldDumpIRFor(functionIndex + info.importFunctionCount()))
+ procedure.setShouldDumpIR();
compilationContext.wasmEntrypointJIT = makeUnique<CCallHelpers>();
Modified: trunk/Source/_javascript_Core/wasm/WasmOMGForOSREntryPlan.cpp (286789 => 286790)
--- trunk/Source/_javascript_Core/wasm/WasmOMGForOSREntryPlan.cpp 2021-12-09 19:01:10 UTC (rev 286789)
+++ trunk/Source/_javascript_Core/wasm/WasmOMGForOSREntryPlan.cpp 2021-12-09 19:07:58 UTC (rev 286790)
@@ -96,7 +96,7 @@
computeExceptionHandlerLocations(exceptionHandlerLocations, internalFunction, context, linkBuffer);
omgEntrypoint.compilation = makeUnique<Compilation>(
- FINALIZE_WASM_CODE_FOR_MODE(CompilationMode::OMGForOSREntryMode, linkBuffer, JITCompilationPtrTag, "WebAssembly OMGForOSREntry function[%i] %s name %s", m_functionIndex, signature.toString().ascii().data(), makeString(IndexOrName(functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace))).ascii().data()),
+ FINALIZE_CODE_IF(context.procedure->shouldDumpIR() || shouldDumpDisassemblyFor(CompilationMode::OMGForOSREntryMode), linkBuffer, JITCompilationPtrTag, "WebAssembly OMGForOSREntry function[%i] %s name %s", m_functionIndex, signature.toString().ascii().data(), makeString(IndexOrName(functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace))).ascii().data()),
WTFMove(context.wasmEntrypointByproducts));
omgEntrypoint.calleeSaveRegisters = WTFMove(internalFunction->entrypoint.calleeSaveRegisters);
Modified: trunk/Source/_javascript_Core/wasm/WasmOMGPlan.cpp (286789 => 286790)
--- trunk/Source/_javascript_Core/wasm/WasmOMGPlan.cpp 2021-12-09 19:01:10 UTC (rev 286789)
+++ trunk/Source/_javascript_Core/wasm/WasmOMGPlan.cpp 2021-12-09 19:07:58 UTC (rev 286790)
@@ -93,7 +93,7 @@
computeExceptionHandlerLocations(exceptionHandlerLocations, internalFunction, context, linkBuffer);
omgEntrypoint.compilation = makeUnique<Compilation>(
- FINALIZE_WASM_CODE_FOR_MODE(CompilationMode::OMGMode, linkBuffer, JITCompilationPtrTag, "WebAssembly OMG function[%i] %s name %s", m_functionIndex, signature.toString().ascii().data(), makeString(IndexOrName(functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace))).ascii().data()),
+ FINALIZE_CODE_IF(context.procedure->shouldDumpIR() || shouldDumpDisassemblyFor(CompilationMode::OMGMode), linkBuffer, JITCompilationPtrTag, "WebAssembly OMG function[%i] %s name %s", m_functionIndex, signature.toString().ascii().data(), makeString(IndexOrName(functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace))).ascii().data()),
WTFMove(context.wasmEntrypointByproducts));
omgEntrypoint.calleeSaveRegisters = WTFMove(internalFunction->entrypoint.calleeSaveRegisters);