summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/passes/ExtractFunction.cpp4
-rw-r--r--src/support/command-line.cpp9
-rw-r--r--src/support/command-line.h14
-rw-r--r--src/tools/optimization-options.h28
-rw-r--r--test/passes/extract-function=foo.txt (renamed from test/passes/extract-function_pass-arg=extract@foo.txt)0
-rw-r--r--test/passes/extract-function=foo.wast (renamed from test/passes/extract-function_pass-arg=extract@foo.wast)0
-rw-r--r--test/passes/extract-function_pass-arg=extract-function@foo.txt28
-rw-r--r--test/passes/extract-function_pass-arg=extract-function@foo.wast36
8 files changed, 104 insertions, 15 deletions
diff --git a/src/passes/ExtractFunction.cpp b/src/passes/ExtractFunction.cpp
index 626ac1ee7..77c0cabb6 100644
--- a/src/passes/ExtractFunction.cpp
+++ b/src/passes/ExtractFunction.cpp
@@ -28,8 +28,8 @@ namespace wasm {
struct ExtractFunction : public Pass {
void run(PassRunner* runner, Module* module) override {
Name name = runner->options.getArgument(
- "extract",
- "ExtractFunction usage: wasm-opt --pass-arg=extract@FUNCTION_NAME");
+ "extract-function",
+ "ExtractFunction usage: wasm-opt --extract-function@FUNCTION_NAME");
std::cerr << "extracting " << name << "\n";
bool found = false;
for (auto& func : module->functions) {
diff --git a/src/support/command-line.cpp b/src/support/command-line.cpp
index 0e638173e..1b9f64295 100644
--- a/src/support/command-line.cpp
+++ b/src/support/command-line.cpp
@@ -136,11 +136,13 @@ void Options::parse(int argc, const char* argv[]) {
// Positional.
switch (positional) {
case Arguments::Zero:
+ // Optional arguments must use --flag=A format, and not separated by
+ // spaces (which would be ambiguous).
+ case Arguments::Optional:
std::cerr << "Unexpected positional argument '" << currentOption
<< "'\n";
exit(EXIT_FAILURE);
case Arguments::One:
- case Arguments::Optional:
if (positionalsSeen) {
std::cerr << "Unexpected second positional argument '"
<< currentOption << "' for " << positionalName << '\n';
@@ -198,11 +200,6 @@ void Options::parse(int argc, const char* argv[]) {
}
break;
case Arguments::Optional:
- if (!argument.size()) {
- if (i + 1 != e) {
- argument = argv[++i];
- }
- }
break;
}
option->action(this, argument);
diff --git a/src/support/command-line.h b/src/support/command-line.h
index 53bdbff28..99d98eec9 100644
--- a/src/support/command-line.h
+++ b/src/support/command-line.h
@@ -34,7 +34,19 @@ namespace wasm {
class Options {
public:
using Action = std::function<void(Options*, const std::string&)>;
- enum class Arguments { Zero, One, N, Optional };
+
+ enum class Arguments {
+ // No arguments.
+ Zero,
+ // One argument, in the form --flag A or --flag=A
+ One,
+ // Multiple arguments, in the form --flag A B C
+ N,
+ // An optional single argument, in the form --flag=A (we disallow --flag A
+ // as that would be ambiguous regarding whether A is another flag, or an
+ // argument to us).
+ Optional
+ };
bool debug;
std::map<std::string, std::string> extra;
diff --git a/src/tools/optimization-options.h b/src/tools/optimization-options.h
index 0e6157473..b7db5d531 100644
--- a/src/tools/optimization-options.h
+++ b/src/tools/optimization-options.h
@@ -202,12 +202,28 @@ struct OptimizationOptions : public ToolOptions {
});
// add passes in registry
for (const auto& p : PassRegistry::get()->getRegisteredNames()) {
- (*this).add(
- std::string("--") + p,
- "",
- PassRegistry::get()->getPassDescription(p),
- Options::Arguments::Zero,
- [this, p](Options*, const std::string&) { passes.push_back(p); });
+ (*this).add(std::string("--") + p,
+ "",
+ PassRegistry::get()->getPassDescription(p),
+ // Allow an optional parameter to a pass. If provided, it is
+ // the same as if using --pass-arg, that is,
+ //
+ // --foo=ARG
+ //
+ // is the same as
+ //
+ // --foo --pass-arg=foo@ARG
+ Options::Arguments::Optional,
+ [this, p](Options*, const std::string& arg) {
+ if (!arg.empty()) {
+ if (passOptions.arguments.count(p)) {
+ Fatal()
+ << "Cannot pass multiple pass arguments to " << p;
+ }
+ passOptions.arguments[p] = arg;
+ }
+ passes.push_back(p);
+ });
}
}
diff --git a/test/passes/extract-function_pass-arg=extract@foo.txt b/test/passes/extract-function=foo.txt
index 3caf274c3..3caf274c3 100644
--- a/test/passes/extract-function_pass-arg=extract@foo.txt
+++ b/test/passes/extract-function=foo.txt
diff --git a/test/passes/extract-function_pass-arg=extract@foo.wast b/test/passes/extract-function=foo.wast
index ab1d8b269..ab1d8b269 100644
--- a/test/passes/extract-function_pass-arg=extract@foo.wast
+++ b/test/passes/extract-function=foo.wast
diff --git a/test/passes/extract-function_pass-arg=extract-function@foo.txt b/test/passes/extract-function_pass-arg=extract-function@foo.txt
new file mode 100644
index 000000000..3caf274c3
--- /dev/null
+++ b/test/passes/extract-function_pass-arg=extract-function@foo.txt
@@ -0,0 +1,28 @@
+(module
+ (type $none_=>_none (func))
+ (import "env" "bar" (func $bar))
+ (export "foo" (func $foo))
+ (func $foo
+ (call $bar)
+ )
+)
+(module
+ (type $none_=>_none (func))
+ (import "env" "other" (func $other))
+ (export "foo" (func $foo))
+ (func $foo
+ (nop)
+ )
+)
+(module
+ (type $none (func))
+ (import "env" "other" (func $other))
+ (table $t 10 funcref)
+ (elem $0 (i32.const 0) $other)
+ (export "foo" (func $foo))
+ (func $foo
+ (call_indirect (type $none)
+ (i32.const 10)
+ )
+ )
+)
diff --git a/test/passes/extract-function_pass-arg=extract-function@foo.wast b/test/passes/extract-function_pass-arg=extract-function@foo.wast
new file mode 100644
index 000000000..ab1d8b269
--- /dev/null
+++ b/test/passes/extract-function_pass-arg=extract-function@foo.wast
@@ -0,0 +1,36 @@
+(module
+ (func $foo
+ (call $bar)
+ )
+ (func $bar
+ (call $foo)
+ )
+ (func $other
+ (drop (i32.const 1))
+ )
+)
+(module
+ ;; Use another function in the table, but the table is not used in the
+ ;; extracted function
+ (table $t 10 funcref)
+ (elem $0 (table $t) (i32.const 0) func $other)
+ (func $foo
+ )
+ (func $other
+ (drop (i32.const 1))
+ )
+)
+(module
+ ;; Use another function in the table, and the table *is* used. As a result,
+ ;; the table and its elements will remain. The called function, $other, will
+ ;; remain as an import that is placed in the table.
+ (type $none (func))
+ (table $t 10 funcref)
+ (elem $0 (table $t) (i32.const 0) func $other)
+ (func $foo
+ (call_indirect (type $none) (i32.const 10))
+ )
+ (func $other
+ (drop (i32.const 1))
+ )
+)