Skip to content

Commit

Permalink
[StackIR] Allow StackIR to be disabled from the commandline (#6725)
Browse files Browse the repository at this point in the history
Normally we use it when optimizing (above a certain level). This lets the user
prevent it from being used even then.

Also add optimization options to wasm-metadce so that this is possible
there as well and not just in wasm-opt (this also opens the door to running
more passes in metadce, which may be useful later).
  • Loading branch information
kripken committed Jul 10, 2024
1 parent 76f6612 commit 37a86d5
Show file tree
Hide file tree
Showing 7 changed files with 737 additions and 78 deletions.
1 change: 1 addition & 0 deletions scripts/fuzz_opt.py
Original file line number Diff line number Diff line change
Expand Up @@ -1565,6 +1565,7 @@ def write_commands(commands, filename):
('--merge-locals',),
('--monomorphize',),
('--monomorphize-always',),
('--no-stack-ir',),
('--once-reduction',),
("--optimize-casts",),
("--optimize-instructions",),
Expand Down
17 changes: 16 additions & 1 deletion src/tools/optimization-options.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,17 @@
namespace wasm {

struct OptimizationOptions : public ToolOptions {
// By default we allow StackIR and enable it by default in higher optimization
// levels, but users can disallow it as well.
bool allowStackIR = true;

void parse(int argc, const char* argv[]) {
ToolOptions::parse(argc, argv);

// After parsing the arguments, update defaults based on the optimize/shrink
// levels.
if (passOptions.optimizeLevel >= 2 || passOptions.shrinkLevel >= 1) {
if (allowStackIR &&
(passOptions.optimizeLevel >= 2 || passOptions.shrinkLevel >= 1)) {
passOptions.generateStackIR = true;
passOptions.optimizeStackIR = true;
}
Expand Down Expand Up @@ -191,6 +196,16 @@ struct OptimizationOptions : public ToolOptions {
[&](Options* o, const std::string& arguments) {
passOptions.debugInfo = true;
})
.add("--no-stack-ir",
"",
"do not use StackIR (even when it is the default)",
ToolOptionsCategory,
Options::Arguments::Zero,
[&](Options* o, const std::string& arguments) {
allowStackIR = false;
passOptions.generateStackIR = false;
passOptions.optimizeStackIR = false;
})
.add("--always-inline-max-function-size",
"-aimfs",
"Max size of functions that are always inlined (default " +
Expand Down
4 changes: 2 additions & 2 deletions src/tools/wasm-metadce.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@
#include "asmjs/shared-constants.h"
#include "ir/element-utils.h"
#include "ir/module-utils.h"
#include "optimization-options.h"
#include "pass.h"
#include "support/colors.h"
#include "support/file.h"
#include "support/json.h"
#include "tool-options.h"
#include "wasm-builder.h"
#include "wasm-io.h"
#include "wasm-validator.h"
Expand Down Expand Up @@ -371,7 +371,7 @@ int main(int argc, const char* argv[]) {

const std::string WasmMetaDCEOption = "wasm-opt options";

ToolOptions options(
OptimizationOptions options(
"wasm-metadce",
"This tool performs dead code elimination (DCE) on a larger space "
"that the wasm module is just a part of. For example, if you have "
Expand Down
721 changes: 646 additions & 75 deletions test/lit/help/wasm-metadce.test

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions test/lit/help/wasm-opt.test
Original file line number Diff line number Diff line change
Expand Up @@ -759,6 +759,9 @@
;; CHECK-NEXT:
;; CHECK-NEXT: --print-stack-ir print StackIR during writing
;; CHECK-NEXT:
;; CHECK-NEXT: --no-stack-ir do not use StackIR (even when it
;; CHECK-NEXT: is the default)
;; CHECK-NEXT:
;; CHECK-NEXT:
;; CHECK-NEXT: General options:
;; CHECK-NEXT: ----------------
Expand Down
3 changes: 3 additions & 0 deletions test/lit/help/wasm2js.test
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,9 @@
;; CHECK-NEXT:
;; CHECK-NEXT: --print-stack-ir print StackIR during writing
;; CHECK-NEXT:
;; CHECK-NEXT: --no-stack-ir do not use StackIR (even when it
;; CHECK-NEXT: is the default)
;; CHECK-NEXT:
;; CHECK-NEXT:
;; CHECK-NEXT: General options:
;; CHECK-NEXT: ----------------
Expand Down
66 changes: 66 additions & 0 deletions test/lit/passes/stack-ir-defaults.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited.

;; Request StackIR explicitly. This optimizes.
;; RUN: wasm-opt %s --generate-stack-ir --optimize-stack-ir -all --print-stack-ir | filecheck %s --check-prefix=REQUESTED

;; As above, but disallow it later. This does not optimize.
;; RUN: wasm-opt %s --generate-stack-ir --optimize-stack-ir -all --no-stack-ir --print-stack-ir | filecheck %s --check-prefix=DISALLOWD

;; As above, but flip it, so we allow it after disallowing. This optimizes.
;; RUN: wasm-opt %s --no-stack-ir --generate-stack-ir --optimize-stack-ir -all --print-stack-ir | filecheck %s --check-prefix=REALLOWED

;; Running -O will use StackIR by default. This optimizes.
;; RUN: wasm-opt %s -O -all --print-stack-ir | filecheck %s --check-prefix=O_DEFAULT

;; As above, but disallow it. This does not optimize.
;; RUN: wasm-opt %s -O --no-stack-ir -all --print-stack-ir | filecheck %s --check-prefix=O__DENIED

;; As above, but flip it. This still does not optimize, as the global state of
;; --no-stack-ir is not overridden (before we explicitly overrode it, while here
;; we -O only requests StackIR if allowed).
;; RUN: wasm-opt %s --no-stack-ir -O -all --print-stack-ir | filecheck %s --check-prefix=O_REALLOW

(module
;; REQUESTED: (import "a" "b" (func $import (type $0) (result i32)))
;; DISALLOWD: (import "a" "b" (func $import (type $0) (result i32)))
;; REALLOWED: (import "a" "b" (func $import (type $0) (result i32)))
;; O_DEFAULT: (import "a" "b" (func $import (type $0) (result i32)))
;; O__DENIED: (import "a" "b" (func $import (type $0) (result i32)))
;; O_REALLOW: (import "a" "b" (func $import (type $0) (result i32)))
(import "a" "b" (func $import (result i32)))

;; REQUESTED: (func $func (type $0) (result i32)
;; REQUESTED-NEXT: call $import
;; REQUESTED-NEXT: unreachable
;; REQUESTED-NEXT: )
;; DISALLOWD: (func $func (type $0) (result i32)
;; DISALLOWD-NEXT: call $import
;; DISALLOWD-NEXT: drop
;; DISALLOWD-NEXT: unreachable
;; DISALLOWD-NEXT: )
;; REALLOWED: (func $func (type $0) (result i32)
;; REALLOWED-NEXT: call $import
;; REALLOWED-NEXT: unreachable
;; REALLOWED-NEXT: )
;; O_DEFAULT: (func $func (type $0) (result i32)
;; O_DEFAULT-NEXT: call $import
;; O_DEFAULT-NEXT: unreachable
;; O_DEFAULT-NEXT: )
;; O__DENIED: (func $func (type $0) (result i32)
;; O__DENIED-NEXT: call $import
;; O__DENIED-NEXT: drop
;; O__DENIED-NEXT: unreachable
;; O__DENIED-NEXT: )
;; O_REALLOW: (func $func (type $0) (result i32)
;; O_REALLOW-NEXT: call $import
;; O_REALLOW-NEXT: drop
;; O_REALLOW-NEXT: unreachable
;; O_REALLOW-NEXT: )
(func $func (export "func") (result i32)
;; This drop can be removed when we optimize using StackIR.
(drop
(call $import)
)
(unreachable)
)
)

0 comments on commit 37a86d5

Please sign in to comment.