diff options
author | Alon Zakai <azakai@google.com> | 2024-07-11 10:31:31 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-11 10:31:31 -0700 |
commit | 5a1daf7727e768acebedd57464d2e0788afc85c5 (patch) | |
tree | 685da7a53cafb6d9a6b9afc3213b386425cf8489 /test/lit/passes/no-inline-monomorphize-inlining.wast | |
parent | e05f7629a27220c9951acc511d6f68a49e7b25d9 (diff) | |
download | binaryen-5a1daf7727e768acebedd57464d2e0788afc85c5.tar.gz binaryen-5a1daf7727e768acebedd57464d2e0788afc85c5.tar.bz2 binaryen-5a1daf7727e768acebedd57464d2e0788afc85c5.zip |
Monomorphization: Optimize constants (#6711)
Previously the pass would monomorphize a call when we were sending more
refined types than the target expects. This generalizes the pass to also consider
the case where we send a constant in a parameter.
To achieve that, this refactors the pass to explicitly define the "call context",
which is the code around the call (inputs and outputs) that may end up leading
to optimization opportunities when combined with the target function. Also
add comments about the overall design + roadmap.
The existing test is mostly unmodified, and the diff there is smaller when
ignoring whitespace. We do "regress" those tests by adding more local.set
operations, as in the refactoring that makes things a lot simpler, that is, to
handle the general case of an operand having either a refined type or be a
constant, we copy it inside the function, which works either way. This
"regression" is only in the testing version of the pass (the normal version
runs optimizations, which would remove that extra code).
This also enables the pass when GC is disabled. Previously we only handled
refined types, so only GC could benefit. Add a test for MVP content
specifically to show we operate there as well.
Diffstat (limited to 'test/lit/passes/no-inline-monomorphize-inlining.wast')
-rw-r--r-- | test/lit/passes/no-inline-monomorphize-inlining.wast | 37 |
1 files changed, 28 insertions, 9 deletions
diff --git a/test/lit/passes/no-inline-monomorphize-inlining.wast b/test/lit/passes/no-inline-monomorphize-inlining.wast index be3b5759d..716d0beda 100644 --- a/test/lit/passes/no-inline-monomorphize-inlining.wast +++ b/test/lit/passes/no-inline-monomorphize-inlining.wast @@ -3,9 +3,12 @@ ;; Monomorphization creates a new function, which we can then inline. When we ;; mark the original as no-inline, we should not inline the copy, as the copy ;; inherits the metadata. +;; +;; Use --optimize-level=3 to ensure inlining works at the maximum (to avoid it +;; not happening because of size limits etc.). -;; RUN: foreach %s %t wasm-opt --no-inline=*noinline* --monomorphize-always --inlining -all -S -o - | filecheck %s --check-prefix NO_INLINE -;; RUN: foreach %s %t wasm-opt --monomorphize-always --inlining -all -S -o - | filecheck %s --check-prefix YESINLINE +;; RUN: foreach %s %t wasm-opt --no-inline=*noinline* --monomorphize-always --inlining --optimize-level=3 -all -S -o - | filecheck %s --check-prefix NO_INLINE +;; RUN: foreach %s %t wasm-opt --monomorphize-always --inlining --optimize-level=3 -all -S -o - | filecheck %s --check-prefix YESINLINE (module ;; NO_INLINE: (type $A (sub (struct ))) @@ -42,7 +45,9 @@ ;; YESINLINE-NEXT: (local $0 (ref $A)) ;; YESINLINE-NEXT: (local $1 (ref $A)) ;; YESINLINE-NEXT: (local $2 (ref $B)) - ;; YESINLINE-NEXT: (local $3 (ref $B)) + ;; YESINLINE-NEXT: (local $3 (ref $A)) + ;; YESINLINE-NEXT: (local $4 (ref $B)) + ;; YESINLINE-NEXT: (local $5 (ref $A)) ;; YESINLINE-NEXT: (block ;; YESINLINE-NEXT: (block $__inlined_func$refinable_noinline ;; YESINLINE-NEXT: (local.set $0 @@ -68,18 +73,28 @@ ;; YESINLINE-NEXT: (local.set $2 ;; YESINLINE-NEXT: (struct.new_default $B) ;; YESINLINE-NEXT: ) - ;; YESINLINE-NEXT: (drop - ;; YESINLINE-NEXT: (local.get $2) + ;; YESINLINE-NEXT: (block + ;; YESINLINE-NEXT: (local.set $3 + ;; YESINLINE-NEXT: (local.get $2) + ;; YESINLINE-NEXT: ) + ;; YESINLINE-NEXT: (drop + ;; YESINLINE-NEXT: (local.get $3) + ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: (block ;; YESINLINE-NEXT: (block $__inlined_func$refinable_noinline_2$3 - ;; YESINLINE-NEXT: (local.set $3 + ;; YESINLINE-NEXT: (local.set $4 ;; YESINLINE-NEXT: (struct.new_default $B) ;; YESINLINE-NEXT: ) - ;; YESINLINE-NEXT: (drop - ;; YESINLINE-NEXT: (local.get $3) + ;; YESINLINE-NEXT: (block + ;; YESINLINE-NEXT: (local.set $5 + ;; YESINLINE-NEXT: (local.get $4) + ;; YESINLINE-NEXT: ) + ;; YESINLINE-NEXT: (drop + ;; YESINLINE-NEXT: (local.get $5) + ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: ) ;; YESINLINE-NEXT: ) @@ -118,7 +133,11 @@ ) ) ) -;; NO_INLINE: (func $refinable_noinline_2 (type $4) (param $ref (ref $B)) +;; NO_INLINE: (func $refinable_noinline_2 (type $4) (param $0 (ref $B)) +;; NO_INLINE-NEXT: (local $ref (ref $A)) +;; NO_INLINE-NEXT: (local.set $ref +;; NO_INLINE-NEXT: (local.get $0) +;; NO_INLINE-NEXT: ) ;; NO_INLINE-NEXT: (drop ;; NO_INLINE-NEXT: (local.get $ref) ;; NO_INLINE-NEXT: ) |