blob: 3c42b6b1f1334f3de8d9846da711790e60cca966 [file] [log] [blame]
/*
* Copyright 2018 WebAssembly Community Group participants
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef wasm_tools_tool_options_h
#define wasm_tools_tool_options_h
#include "ir/module-utils.h"
#include "pass.h"
#include "support/command-line.h"
//
// Shared options for commandline tools
//
namespace wasm {
struct ToolOptions : public Options {
PassOptions passOptions;
bool quiet = false;
bool preserveTypeOrder = false;
IRProfile profile = IRProfile::Normal;
constexpr static const char* ToolOptionsCategory = "Tool options";
ToolOptions(const std::string& command, const std::string& description)
: Options(command, description) {
(*this)
.add("--mvp-features",
"-mvp",
"Disable all non-MVP features",
ToolOptionsCategory,
Arguments::Zero,
[this](Options*, const std::string&) {
enabledFeatures.setMVP();
disabledFeatures.setAll();
})
.add("--all-features",
"-all",
"Enable all features",
ToolOptionsCategory,
Arguments::Zero,
[this](Options*, const std::string&) {
enabledFeatures.setAll();
disabledFeatures.setMVP();
})
.add("--detect-features",
"",
"(deprecated - this flag does nothing)",
ToolOptionsCategory,
Arguments::Zero,
[](Options*, const std::string&) {})
.add("--quiet",
"-q",
"Emit less verbose output and hide trivial warnings.",
ToolOptionsCategory,
Arguments::Zero,
[this](Options*, const std::string&) { quiet = true; })
.add(
"--experimental-poppy",
"",
"Parse wast files as Poppy IR for testing purposes.",
ToolOptionsCategory,
Arguments::Zero,
[this](Options*, const std::string&) { profile = IRProfile::Poppy; });
(*this)
.addFeature(FeatureSet::SignExt, "sign extension operations")
.addFeature(FeatureSet::Atomics, "atomic operations")
.addFeature(FeatureSet::MutableGlobals, "mutable globals")
.addFeature(FeatureSet::TruncSat, "nontrapping float-to-int operations")
.addFeature(FeatureSet::SIMD, "SIMD operations and types")
.addFeature(FeatureSet::BulkMemory,
"bulk memory operations",
FeatureSet(FeatureSet::BulkMemoryOpt))
.addFeature(FeatureSet::BulkMemoryOpt,
"memory.copy and memory.fill",
FeatureSet::None,
FeatureSet(FeatureSet::BulkMemory))
.addFeature(FeatureSet::CallIndirectOverlong,
"LEB encoding of call-indirect (Ignored for compatibility as "
"it has no effect on Binaryen)")
.addFeature(FeatureSet::ExceptionHandling,
"exception handling operations")
.addFeature(FeatureSet::TailCall, "tail call operations")
.addFeature(FeatureSet::ReferenceTypes, "reference types")
.addFeature(FeatureSet::Multivalue, "multivalue functions")
.addFeature(FeatureSet::GC, "garbage collection")
.addFeature(FeatureSet::Memory64, "memory64")
.addFeature(FeatureSet::RelaxedSIMD, "relaxed SIMD")
.addFeature(FeatureSet::ExtendedConst, "extended const expressions")
.addFeature(FeatureSet::Strings, "strings")
.addFeature(FeatureSet::MultiMemory, "multimemory")
.addFeature(FeatureSet::StackSwitching, "stack switching")
.addFeature(FeatureSet::SharedEverything, "shared-everything threads")
.addFeature(FeatureSet::FP16, "float 16 operations")
.addFeature(FeatureSet::CustomDescriptors,
"custom descriptors (RTTs) and exact references")
.add("--enable-typed-function-references",
"",
"Deprecated compatibility flag",
ToolOptionsCategory,
Options::Arguments::Zero,
[](Options* o, const std::string& argument) {
std::cerr
<< "Warning: Typed function references have been made part of "
"GC and --enable-typed-function-references is deprecated\n";
})
.add("--disable-typed-function-references",
"",
"Deprecated compatibility flag",
ToolOptionsCategory,
Options::Arguments::Zero,
[](Options* o, const std::string& argument) {
std::cerr
<< "Warning: Typed function references have been made part of "
"GC and --disable-typed-function-references is deprecated\n";
})
.add("--no-validation",
"-n",
"Disables validation, assumes inputs are correct",
ToolOptionsCategory,
Options::Arguments::Zero,
[this](Options* o, const std::string& argument) {
passOptions.validate = false;
})
.add("--pass-arg",
"-pa",
"An argument passed along to optimization passes being run. Must be "
"in the form KEY@VALUE. If KEY is the name of a pass then it "
"applies to the closest instance of that pass before us. If KEY is "
"not the name of a pass then it is a global option that applies to "
"all pass instances that read it.",
ToolOptionsCategory,
Options::Arguments::N,
[this](Options*, const std::string& argument) {
std::string key, value;
auto colon = argument.find('@');
if (colon == std::string::npos) {
key = argument;
value = "1";
} else {
key = argument.substr(0, colon);
value = argument.substr(colon + 1);
}
addPassArg(key, value);
})
.add(
"--closed-world",
"-cw",
"Assume code outside of the module does not inspect or interact with "
"GC and function references, even if they are passed out. The outside "
"may hold on to them and pass them back in, but not inspect their "
"contents or call them.",
ToolOptionsCategory,
Options::Arguments::Zero,
[this](Options*, const std::string&) {
passOptions.closedWorld = true;
})
.add(
"--preserve-type-order",
"",
"Preserve the order of types from the input (useful for debugging and "
"testing)",
ToolOptionsCategory,
Options::Arguments::Zero,
[&](Options* o, const std::string& arguments) {
preserveTypeOrder = true;
})
.add("--generate-stack-ir",
"",
"generate StackIR during writing",
ToolOptionsCategory,
Options::Arguments::Zero,
[&](Options* o, const std::string& arguments) {
passOptions.generateStackIR = true;
})
.add("--optimize-stack-ir",
"",
"optimize StackIR during writing",
ToolOptionsCategory,
Options::Arguments::Zero,
[&](Options* o, const std::string& arguments) {
// Also generate StackIR, to have something to optimize.
passOptions.generateStackIR = true;
passOptions.optimizeStackIR = true;
})
.add("--print-stack-ir",
"",
"print StackIR during writing",
ToolOptionsCategory,
Options::Arguments::Zero,
[&](Options* o, const std::string& arguments) {
// Also generate StackIR, to have something to print.
passOptions.generateStackIR = true;
passOptions.printStackIR = &std::cout;
});
}
ToolOptions& addFeature(FeatureSet::Feature feature,
const std::string& description,
FeatureSet impliedEnable = FeatureSet::None,
FeatureSet impliedDisable = FeatureSet::None) {
(*this)
.add(std::string("--enable-") + FeatureSet::toString(feature),
"",
std::string("Enable ") + description,
ToolOptionsCategory,
Arguments::Zero,
[this, feature, impliedEnable](Options*, const std::string&) {
enabledFeatures.set(feature | impliedEnable, true);
disabledFeatures.set(feature | impliedEnable, false);
})
.add(std::string("--disable-") + FeatureSet::toString(feature),
"",
std::string("Disable ") + description,
ToolOptionsCategory,
Arguments::Zero,
[this, feature, impliedDisable](Options*, const std::string&) {
enabledFeatures.set(feature | impliedDisable, false);
disabledFeatures.set(feature | impliedDisable, true);
});
return *this;
}
void applyOptionsBeforeParse(Module& module) const {
module.features.enable(enabledFeatures);
module.features.disable(disabledFeatures);
}
void applyOptionsAfterParse(Module& module) const {
if (!preserveTypeOrder) {
module.typeIndices.clear();
}
}
virtual void addPassArg(const std::string& key, const std::string& value) {
passOptions.arguments[key] = value;
}
virtual ~ToolOptions() = default;
private:
FeatureSet enabledFeatures = FeatureSet::Default;
FeatureSet disabledFeatures = FeatureSet::None;
};
} // namespace wasm
#endif