summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ir/names.h4
-rw-r--r--src/tools/wasm-split/instrumenter.cpp77
-rw-r--r--src/tools/wasm-split/instrumenter.h25
-rw-r--r--src/tools/wasm-split/split-options.cpp31
-rw-r--r--src/tools/wasm-split/split-options.h2
-rw-r--r--src/tools/wasm-split/wasm-split.cpp11
-rw-r--r--test/lit/help/wasm-split.test22
-rw-r--r--test/lit/wasm-split/instrument-in-secondary-memory-custom-names.wast31
-rw-r--r--test/lit/wasm-split/instrument-in-secondary-memory.wast92
-rw-r--r--test/lit/wasm-split/invalid-options.wast13
10 files changed, 270 insertions, 38 deletions
diff --git a/src/ir/names.h b/src/ir/names.h
index 4bdfacb1e..b2165c2c2 100644
--- a/src/ir/names.h
+++ b/src/ir/names.h
@@ -83,6 +83,10 @@ inline Name getValidElementSegmentName(Module& module, Name root) {
return getValidName(
root, [&](Name test) { return !module.getElementSegmentOrNull(test); });
}
+inline Name getValidMemoryName(Module& module, Name root) {
+ return getValidName(root,
+ [&](Name test) { return !module.getMemoryOrNull(test); });
+}
inline Name getValidLocalName(Function& func, Name root) {
return getValidName(root,
[&](Name test) { return !func.hasLocalIndex(test); });
diff --git a/src/tools/wasm-split/instrumenter.cpp b/src/tools/wasm-split/instrumenter.cpp
index 50da9d034..7f9ff9c75 100644
--- a/src/tools/wasm-split/instrumenter.cpp
+++ b/src/tools/wasm-split/instrumenter.cpp
@@ -22,25 +22,31 @@
namespace wasm {
-Instrumenter::Instrumenter(const WasmSplitOptions& options, uint64_t moduleHash)
- : options(options), moduleHash(moduleHash) {}
+Instrumenter::Instrumenter(const InstrumenterConfig& config,
+ uint64_t moduleHash)
+ : config(config), moduleHash(moduleHash) {}
void Instrumenter::run(PassRunner* runner, Module* wasm) {
this->runner = runner;
this->wasm = wasm;
- addGlobals();
+
+ size_t numFuncs = 0;
+ ModuleUtils::iterDefinedFunctions(*wasm, [&](Function*) { ++numFuncs; });
+
+ addGlobals(numFuncs);
+ addSecondaryMemory(numFuncs);
instrumentFuncs();
- addProfileExport();
+ addProfileExport(numFuncs);
}
-void Instrumenter::addGlobals() {
- if (options.storageKind != WasmSplitOptions::StorageKind::InGlobals) {
+void Instrumenter::addGlobals(size_t numFuncs) {
+ if (config.storageKind != WasmSplitOptions::StorageKind::InGlobals) {
// Don't need globals
return;
}
// Create fresh global names (over-reserves, but that's ok)
counterGlobal = Names::getValidGlobalName(*wasm, "monotonic_counter");
- functionGlobals.reserve(wasm->functions.size());
+ functionGlobals.reserve(numFuncs);
ModuleUtils::iterDefinedFunctions(*wasm, [&](Function* func) {
functionGlobals.push_back(Names::getValidGlobalName(
*wasm, std::string(func->name.c_str()) + "_timestamp"));
@@ -62,11 +68,31 @@ void Instrumenter::addGlobals() {
}
}
+void Instrumenter::addSecondaryMemory(size_t numFuncs) {
+ if (config.storageKind != WasmSplitOptions::StorageKind::InSecondaryMemory) {
+ // Don't need secondary memory
+ return;
+ }
+ if (!wasm->features.hasMultiMemories()) {
+ Fatal()
+ << "error: --in-secondary-memory requires multi-memories to be enabled";
+ }
+
+ secondaryMemory =
+ Names::getValidMemoryName(*wasm, config.secondaryMemoryName);
+ // Create a memory with enough pages to write into
+ size_t pages = (numFuncs + Memory::kPageSize - 1) / Memory::kPageSize;
+ auto mem = Builder::makeMemory(secondaryMemory, pages, pages, true);
+ mem->module = config.importNamespace;
+ mem->base = config.secondaryMemoryName;
+ wasm->addMemory(std::move(mem));
+}
+
void Instrumenter::instrumentFuncs() {
// Inject code at the beginning of each function to advance the monotonic
// counter and set the function's timestamp if it hasn't already been set.
Builder builder(*wasm);
- switch (options.storageKind) {
+ switch (config.storageKind) {
case WasmSplitOptions::StorageKind::InGlobals: {
// (if (i32.eqz (global.get $timestamp))
// (block
@@ -102,13 +128,22 @@ void Instrumenter::instrumentFuncs() {
});
break;
}
- case WasmSplitOptions::StorageKind::InMemory: {
+ case WasmSplitOptions::StorageKind::InMemory:
+ case WasmSplitOptions::StorageKind::InSecondaryMemory: {
if (!wasm->features.hasAtomics()) {
- Fatal() << "error: --in-memory requires atomics to be enabled";
+ const char* command =
+ config.storageKind == WasmSplitOptions::StorageKind::InMemory
+ ? "in-memory"
+ : "in-secondary-memory";
+ Fatal() << "error: --" << command << " requires atomics to be enabled";
}
// (i32.atomic.store8 offset=funcidx (i32.const 0) (i32.const 1))
Index funcIdx = 0;
assert(!wasm->memories.empty());
+ Name memoryName =
+ config.storageKind == WasmSplitOptions::StorageKind::InMemory
+ ? wasm->memories[0]->name
+ : secondaryMemory;
ModuleUtils::iterDefinedFunctions(*wasm, [&](Function* func) {
func->body = builder.makeSequence(
builder.makeAtomicStore(1,
@@ -116,7 +151,7 @@ void Instrumenter::instrumentFuncs() {
builder.makeConstPtr(0, Type::i32),
builder.makeConst(uint32_t(1)),
Type::i32,
- wasm->memories[0]->name),
+ memoryName),
func->body,
func->body->type);
++funcIdx;
@@ -141,21 +176,18 @@ void Instrumenter::instrumentFuncs() {
// otherwise. Functions with smaller non-zero timestamps were called earlier in
// the instrumented run than funtions with larger timestamps.
-void Instrumenter::addProfileExport() {
+void Instrumenter::addProfileExport(size_t numFuncs) {
// Create and export a function to dump the profile into a given memory
// buffer. The function takes the available address and buffer size as
// arguments and returns the total size of the profile. It only actually
// writes the profile if the given space is sufficient to hold it.
- auto name = Names::getValidFunctionName(*wasm, options.profileExport);
+ auto name = Names::getValidFunctionName(*wasm, config.profileExport);
auto writeProfile = Builder::makeFunction(
name, Signature({Type::i32, Type::i32}, Type::i32), {});
writeProfile->hasExplicitName = true;
writeProfile->setLocalName(0, "addr");
writeProfile->setLocalName(1, "size");
- size_t numFuncs = 0;
- ModuleUtils::iterDefinedFunctions(*wasm, [&](Function*) { ++numFuncs; });
-
// Calculate the size of the profile:
// 8 bytes module hash +
// 4 bytes for the timestamp for each function
@@ -188,7 +220,7 @@ void Instrumenter::addProfileExport() {
8, 0, 1, getAddr(), hashConst(), Type::i64, wasm->memories[0]->name);
uint32_t offset = 8;
- switch (options.storageKind) {
+ switch (config.storageKind) {
case WasmSplitOptions::StorageKind::InGlobals: {
for (const auto& global : functionGlobals) {
writeData = builder.blockify(
@@ -204,12 +236,17 @@ void Instrumenter::addProfileExport() {
}
break;
}
- case WasmSplitOptions::StorageKind::InMemory: {
+ case WasmSplitOptions::StorageKind::InMemory:
+ case WasmSplitOptions::StorageKind::InSecondaryMemory: {
Index funcIdxVar =
Builder::addVar(writeProfile.get(), "funcIdx", Type::i32);
auto getFuncIdx = [&]() {
return builder.makeLocalGet(funcIdxVar, Type::i32);
};
+ Name loadMemoryName =
+ config.storageKind == WasmSplitOptions::StorageKind::InMemory
+ ? wasm->memories[0]->name
+ : secondaryMemory;
// (block $outer
// (loop $l
// (br_if $outer (i32.eq (local.get $fucIdx) (i32.const numFuncs))
@@ -249,7 +286,7 @@ void Instrumenter::addProfileExport() {
builder.makeBinary(
MulInt32, getFuncIdx(), builder.makeConst(uint32_t(4)))),
builder.makeAtomicLoad(
- 1, 0, getFuncIdx(), Type::i32, wasm->memories[0]->name),
+ 1, 0, getFuncIdx(), Type::i32, loadMemoryName),
Type::i32,
wasm->memories[0]->name),
builder.makeLocalSet(
@@ -269,7 +306,7 @@ void Instrumenter::addProfileExport() {
// Create an export for the function
wasm->addFunction(std::move(writeProfile));
wasm->addExport(
- Builder::makeExport(options.profileExport, name, ExternalKind::Function));
+ Builder::makeExport(config.profileExport, name, ExternalKind::Function));
// Export the memory if it is not already exported or imported.
if (!wasm->memories[0]->imported()) {
diff --git a/src/tools/wasm-split/instrumenter.h b/src/tools/wasm-split/instrumenter.h
index 7de5a9135..f4f2f2119 100644
--- a/src/tools/wasm-split/instrumenter.h
+++ b/src/tools/wasm-split/instrumenter.h
@@ -23,6 +23,20 @@
namespace wasm {
+struct InstrumenterConfig {
+ // The namespace from which to import the secondary memory
+ Name importNamespace = "env";
+ // The name of the secondary memory created to store profile data during
+ // instrumentation
+ Name secondaryMemoryName = "profile-data";
+ // Where to store the profile data
+ WasmSplitOptions::StorageKind storageKind =
+ WasmSplitOptions::StorageKind::InGlobals;
+ // The export name of the function the embedder calls to write the profile
+ // into memory
+ std::string profileExport = DEFAULT_PROFILE_EXPORT;
+};
+
// Add a global monotonic counter and a timestamp global for each function, code
// at the beginning of each function to set its timestamp, and a new exported
// function for dumping the profile data.
@@ -30,20 +44,23 @@ struct Instrumenter : public Pass {
PassRunner* runner = nullptr;
Module* wasm = nullptr;
- const WasmSplitOptions& options;
+ const InstrumenterConfig& config;
uint64_t moduleHash;
Name counterGlobal;
std::vector<Name> functionGlobals;
- Instrumenter(const WasmSplitOptions& options, uint64_t moduleHash);
+ Name secondaryMemory;
+
+ Instrumenter(const InstrumenterConfig& config, uint64_t moduleHash);
void run(PassRunner* runner, Module* wasm) override;
private:
- void addGlobals();
+ void addGlobals(size_t numFuncs);
+ void addSecondaryMemory(size_t numFuncs);
void instrumentFuncs();
- void addProfileExport();
+ void addProfileExport(size_t numFuncs);
};
} // namespace wasm
diff --git a/src/tools/wasm-split/split-options.cpp b/src/tools/wasm-split/split-options.cpp
index b8ccde83e..d077c70bc 100644
--- a/src/tools/wasm-split/split-options.cpp
+++ b/src/tools/wasm-split/split-options.cpp
@@ -185,10 +185,12 @@ WasmSplitOptions::WasmSplitOptions()
[&](Options* o, const std::string& argument) { placeholderMap = true; })
.add("--import-namespace",
"",
- "The namespace from which to import objects from the primary "
- "module into the secondary module.",
+ "When provided as an option for module splitting, the namespace from "
+ "which to import objects from the primary "
+ "module into the secondary module. In instrument mode, refers to the "
+ "namespace from which to import the secondary memory, if any.",
WasmSplitOption,
- {Mode::Split},
+ {Mode::Split, Mode::Instrument},
Options::Arguments::One,
[&](Options* o, const std::string& argument) {
importNamespace = argument;
@@ -246,6 +248,29 @@ WasmSplitOptions::WasmSplitOptions()
storageKind = StorageKind::InMemory;
})
.add(
+ "--in-secondary-memory",
+ "",
+ "Store profile information in a separate memory, rather than in module "
+ "main memory or globals (the default). With this option, users do not "
+ "need to reserve the initial memory region for profile data and the "
+ "data can be shared between multiple threads.",
+ WasmSplitOption,
+ {Mode::Instrument},
+ Options::Arguments::Zero,
+ [&](Options* o, const std::string& argument) {
+ storageKind = StorageKind::InSecondaryMemory;
+ })
+ .add("--secondary-memory-name",
+ "",
+ "The name of the secondary memory created to store profile "
+ "information.",
+ WasmSplitOption,
+ {Mode::Instrument},
+ Options::Arguments::One,
+ [&](Options* o, const std::string& argument) {
+ secondaryMemoryName = argument;
+ })
+ .add(
"--emit-module-names",
"",
"Emit module names, even if not emitting the rest of the names section. "
diff --git a/src/tools/wasm-split/split-options.h b/src/tools/wasm-split/split-options.h
index 9f6253626..5aba0ba39 100644
--- a/src/tools/wasm-split/split-options.h
+++ b/src/tools/wasm-split/split-options.h
@@ -37,6 +37,7 @@ struct WasmSplitOptions : ToolOptions {
enum class StorageKind : unsigned {
InGlobals, // Store profile data in WebAssembly Globals
InMemory, // Store profile data in memory, accessible from all threads
+ InSecondaryMemory, // Store profile data in memory separate from main memory
};
StorageKind storageKind = StorageKind::InGlobals;
@@ -63,6 +64,7 @@ struct WasmSplitOptions : ToolOptions {
std::string importNamespace;
std::string placeholderNamespace;
+ std::string secondaryMemoryName;
std::string exportPrefix;
// A hack to ensure the split and instrumented modules have the same table
diff --git a/src/tools/wasm-split/wasm-split.cpp b/src/tools/wasm-split/wasm-split.cpp
index 43db1b7d2..ec1f5555c 100644
--- a/src/tools/wasm-split/wasm-split.cpp
+++ b/src/tools/wasm-split/wasm-split.cpp
@@ -111,7 +111,16 @@ void instrumentModule(const WasmSplitOptions& options) {
uint64_t moduleHash = hashFile(options.inputFiles[0]);
PassRunner runner(&wasm, options.passOptions);
- Instrumenter(options, moduleHash).run(&runner, &wasm);
+ InstrumenterConfig config;
+ if (options.importNamespace.size()) {
+ config.importNamespace = options.importNamespace;
+ }
+ if (options.secondaryMemoryName.size()) {
+ config.secondaryMemoryName = options.secondaryMemoryName;
+ }
+ config.storageKind = options.storageKind;
+ config.profileExport = options.profileExport;
+ Instrumenter(config, moduleHash).run(&runner, &wasm);
adjustTableSize(wasm, options.initialTableSize);
diff --git a/test/lit/help/wasm-split.test b/test/lit/help/wasm-split.test
index 1994c681a..2e798b077 100644
--- a/test/lit/help/wasm-split.test
+++ b/test/lit/help/wasm-split.test
@@ -54,9 +54,13 @@
;; CHECK-NEXT: --placeholdermap [split] Write a file mapping placeholder
;; CHECK-NEXT: indices to the function names.
;; CHECK-NEXT:
-;; CHECK-NEXT: --import-namespace [split] The namespace from which to import
-;; CHECK-NEXT: objects from the primary module into the
-;; CHECK-NEXT: secondary module.
+;; CHECK-NEXT: --import-namespace [split, instrument] When provided as an
+;; CHECK-NEXT: option for module splitting, the namespace
+;; CHECK-NEXT: from which to import objects from the
+;; CHECK-NEXT: primary module into the secondary module.
+;; CHECK-NEXT: In instrument mode, refers to the
+;; CHECK-NEXT: namespace from which to import the
+;; CHECK-NEXT: secondary memory, if any.
;; CHECK-NEXT:
;; CHECK-NEXT: --placeholder-namespace [split] The namespace from which to import
;; CHECK-NEXT: placeholder functions into the primary
@@ -85,6 +89,18 @@
;; CHECK-NEXT: does not use the initial memory region for
;; CHECK-NEXT: anything else.
;; CHECK-NEXT:
+;; CHECK-NEXT: --in-secondary-memory [instrument] Store profile information in
+;; CHECK-NEXT: a separate memory, rather than in module
+;; CHECK-NEXT: main memory or globals (the default). With
+;; CHECK-NEXT: this option, users do not need to reserve
+;; CHECK-NEXT: the initial memory region for profile data
+;; CHECK-NEXT: and the data can be shared between
+;; CHECK-NEXT: multiple threads.
+;; CHECK-NEXT:
+;; CHECK-NEXT: --secondary-memory-name [instrument] The name of the secondary
+;; CHECK-NEXT: memory created to store profile
+;; CHECK-NEXT: information.
+;; CHECK-NEXT:
;; CHECK-NEXT: --emit-module-names [split, instrument] Emit module names,
;; CHECK-NEXT: even if not emitting the rest of the names
;; CHECK-NEXT: section. Can help differentiate the
diff --git a/test/lit/wasm-split/instrument-in-secondary-memory-custom-names.wast b/test/lit/wasm-split/instrument-in-secondary-memory-custom-names.wast
new file mode 100644
index 000000000..9035a0b8b
--- /dev/null
+++ b/test/lit/wasm-split/instrument-in-secondary-memory-custom-names.wast
@@ -0,0 +1,31 @@
+;; RUN: wasm-split %s --instrument --in-secondary-memory --import-namespace=custom_env --secondary-memory-name=custom_name -all -S -o - | filecheck %s
+
+;; Check that the output round trips and validates as well
+;; RUN: wasm-split %s --instrument --in-secondary-memory -all -g -o %t.wasm
+;; RUN: wasm-opt -all %t.wasm -S -o -
+
+(module
+ (import "env" "foo" (func $foo))
+ (export "bar" (func $bar))
+ (memory $0 1 1)
+ (func $bar
+ (call $foo)
+ )
+ (func $baz (param i32) (result i32)
+ (local.get 0)
+ )
+)
+
+;; Check that a memory import has been added for secondary memory
+;; CHECK: (import "custom_env" "custom_name" (memory $custom_name (shared 1 1)))
+
+;; And the profiling function exported
+;; CHECK: (export "__write_profile" (func $__write_profile))
+
+;; And main memory has been exported
+;; CHECK: (export "profile-memory" (memory $0))
+
+;; Check that the function instrumentation uses the correct memory name
+;; CHECK: (i32.atomic.store8 $custom_name
+;; CHECK: (i32.atomic.store8 $custom_name offset=1
+;; CHECK: (i32.atomic.load8_u $custom_name
diff --git a/test/lit/wasm-split/instrument-in-secondary-memory.wast b/test/lit/wasm-split/instrument-in-secondary-memory.wast
new file mode 100644
index 000000000..3e012293b
--- /dev/null
+++ b/test/lit/wasm-split/instrument-in-secondary-memory.wast
@@ -0,0 +1,92 @@
+;; RUN: wasm-split %s --instrument --in-secondary-memory -all -S -o - | filecheck %s
+
+;; Check that the output round trips and validates as well
+;; RUN: wasm-split %s --instrument --in-secondary-memory -all -g -o %t.wasm
+;; RUN: wasm-opt -all %t.wasm -S -o -
+
+(module
+ (import "env" "foo" (func $foo))
+ (export "bar" (func $bar))
+ (memory $0 1 1)
+ (func $bar
+ (call $foo)
+ )
+ (func $baz (param i32) (result i32)
+ (local.get 0)
+ )
+)
+
+;; Check that a memory import has been added for secondary memory
+;; CHECK: (import "env" "profile-data" (memory $profile-data (shared 1 1)))
+
+;; And the profiling function exported
+;; CHECK: (export "__write_profile" (func $__write_profile))
+
+;; And main memory has been exported
+;; CHECK: (export "profile-memory" (memory $0))
+
+;; Check that the function instrumentation is correct
+
+;; CHECK: (func $bar
+;; CHECK-NEXT: (i32.atomic.store8 $profile-data
+;; CHECK-NEXT: (i32.const 0)
+;; CHECK-NEXT: (i32.const 1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (call $foo)
+;; CHECK-NEXT: )
+
+;; CHECK-NEXT: (func $baz (param $0 i32) (result i32)
+;; CHECK-NEXT: (i32.atomic.store8 $profile-data offset=1
+;; CHECK-NEXT: (i32.const 0)
+;; CHECK-NEXT: (i32.const 1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+
+;; Check that the profiling function is correct.
+
+;; CHECK: (func $__write_profile (param $addr i32) (param $size i32) (result i32)
+;; CHECK-NEXT: (local $funcIdx i32)
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (i32.ge_u
+;; CHECK-NEXT: (local.get $size)
+;; CHECK-NEXT: (i32.const 16)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (i64.store $0 align=1
+;; CHECK-NEXT: (local.get $addr)
+;; CHECK-NEXT: (i64.const {{.*}})
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block $outer
+;; CHECK-NEXT: (loop $l
+;; CHECK-NEXT: (br_if $outer
+;; CHECK-NEXT: (i32.eq
+;; CHECK-NEXT: (local.get $funcIdx)
+;; CHECK-NEXT: (i32.const 2)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.store $0 offset=8
+;; CHECK-NEXT: (i32.add
+;; CHECK-NEXT: (local.get $addr)
+;; CHECK-NEXT: (i32.mul
+;; CHECK-NEXT: (local.get $funcIdx)
+;; CHECK-NEXT: (i32.const 4)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.atomic.load8_u $profile-data
+;; CHECK-NEXT: (local.get $funcIdx)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.set $funcIdx
+;; CHECK-NEXT: (i32.add
+;; CHECK-NEXT: (local.get $funcIdx)
+;; CHECK-NEXT: (i32.const 1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (br $l)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.const 16)
+;; CHECK-NEXT: )
diff --git a/test/lit/wasm-split/invalid-options.wast b/test/lit/wasm-split/invalid-options.wast
index 2f9c0a148..c5a56b579 100644
--- a/test/lit/wasm-split/invalid-options.wast
+++ b/test/lit/wasm-split/invalid-options.wast
@@ -17,14 +17,9 @@
;; RUN: not wasm-split %s --instrument --symbolmap 2>&1 \
;; RUN: | filecheck %s --check-prefix INSTRUMENT-SYMBOLMAP
-;; --instrument cannot be used with --import-namespace
-;; RUN: not wasm-split %s --instrument --import-namespace=foo 2>&1 \
-;; RUN: | filecheck %s --check-prefix INSTRUMENT-IMPORT-NS
-
;; --instrument cannot be used with --placeholder-namespace
;; RUN: not wasm-split %s --instrument --placeholder-namespace=foo 2>&1 \
;; RUN: | filecheck %s --check-prefix INSTRUMENT-PLACEHOLDER-NS
-
;; --instrument cannot be used with --export-prefix
;; RUN: not wasm-split %s --instrument --export-prefix=foo 2>&1 \
;; RUN: | filecheck %s --check-prefix INSTRUMENT-EXPORT-PREFIX
@@ -45,6 +40,10 @@
;; RUN: not wasm-split %s --profile-export=foo 2>&1 \
;; RUN: | filecheck %s --check-prefix SPLIT-PROFILE-EXPORT
+;; --secondary-memory-name cannot be used with Split mode
+;; RUN: not wasm-split %s --secondary-memory-name=foo 2>&1 \
+;; RUN: | filecheck %s --check-prefix SPLIT-SECONDARY-MEMORY-NAME
+
;; -S cannot be used with --merge-profiles
;; RUN: not wasm-split %s --merge-profiles -S 2>&1 \
;; RUN: | filecheck %s --check-prefix MERGE-EMIT-TEXT
@@ -73,8 +72,6 @@
;; INSTRUMENT-SYMBOLMAP: error: Option --symbolmap cannot be used in instrument mode.
-;; INSTRUMENT-IMPORT-NS: error: Option --import-namespace cannot be used in instrument mode.
-
;; INSTRUMENT-PLACEHOLDER-NS: error: Option --placeholder-namespace cannot be used in instrument mode.
;; INSTRUMENT-EXPORT-PREFIX: error: Option --export-prefix cannot be used in instrument mode.
@@ -87,6 +84,8 @@
;; SPLIT-PROFILE-EXPORT: error: Option --profile-export cannot be used in split mode.
+;; SPLIT-SECONDARY-MEMORY-NAME: error: Option --secondary-memory-name cannot be used in split mode.
+
;; MERGE-EMIT-TEXT: error: Option --emit-text cannot be used in merge-profiles mode.
;; MERGE-DEBUGINFO: error: Option --debuginfo cannot be used in merge-profiles mode.