From eafc986a57b5a79100cb7336ac3ed42ec3186845 Mon Sep 17 00:00:00 2001 From: paul-hoang <96213640+paul-hoang@users.noreply.github.com> Date: Sat, 3 May 2025 00:28:59 -0700 Subject: [PATCH 1/4] call.without.effects is always possible for CSE --- src/passes/LocalCSE.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/passes/LocalCSE.cpp b/src/passes/LocalCSE.cpp index 78f722c7ae5..8c77321ac15 100644 --- a/src/passes/LocalCSE.cpp +++ b/src/passes/LocalCSE.cpp @@ -118,6 +118,7 @@ #include #include +#include #include #include #include @@ -363,6 +364,11 @@ struct Scanner // total size big enough - while isPossible checks conditions that prevent // using an expression at all. bool isPossible(Expression* curr) { + // call.without.effects is always possible for CSE. + if (Intrinsics(*getModule()).isCallWithoutEffects(curr)) { + return; + } + // We will fully compute effects later, but consider shallow effects at this // early time to ignore things that cannot be optimized later, because we // use a greedy algorithm. Specifically, imagine we see this: From 9eee2aabcf4aa56799036829b20e995b5096d670 Mon Sep 17 00:00:00 2001 From: paul-hoang <96213640+paul-hoang@users.noreply.github.com> Date: Sat, 3 May 2025 00:30:06 -0700 Subject: [PATCH 2/4] Update LocalCSE.cpp --- src/passes/LocalCSE.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/passes/LocalCSE.cpp b/src/passes/LocalCSE.cpp index 8c77321ac15..9b68cfa8bf5 100644 --- a/src/passes/LocalCSE.cpp +++ b/src/passes/LocalCSE.cpp @@ -366,7 +366,7 @@ struct Scanner bool isPossible(Expression* curr) { // call.without.effects is always possible for CSE. if (Intrinsics(*getModule()).isCallWithoutEffects(curr)) { - return; + return true; } // We will fully compute effects later, but consider shallow effects at this From b7fbfc1f128ce9f22cde518edbf34b650e176311 Mon Sep 17 00:00:00 2001 From: paul-hoang <96213640+paul-hoang@users.noreply.github.com> Date: Sat, 3 May 2025 08:06:33 +0000 Subject: [PATCH 3/4] add test --- .../local-cse_call-without-effects.wast | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 test/lit/passes/local-cse_call-without-effects.wast diff --git a/test/lit/passes/local-cse_call-without-effects.wast b/test/lit/passes/local-cse_call-without-effects.wast new file mode 100644 index 00000000000..02d3eac4907 --- /dev/null +++ b/test/lit/passes/local-cse_call-without-effects.wast @@ -0,0 +1,29 @@ +;; RUN: foreach %s %t wasm-opt --local-cse --intrinsic-lowering -S -o - | filecheck %s + +(module + (import "binaryen-intrinsics" "call.without.effects" (func $cwe-ii-i (param i32 i32 funcref) (result i32))) + + (func $add (param $0 i32) (param $1 i32) (result i32) + (i32.add (local.get $0) (local.get $1)) + ) + + (func $test (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local.set $2 + (call $cwe-ii-i + (local.get $0) + (local.get $1) + (ref.func $add) + ) + ) + (local.set $3 + (call $cwe-ii-i + (local.get $0) + (local.get $1) + (ref.func $add) + ) + ) + (return (i32.add (local.get $2) (local.get $3))) + ) +) \ No newline at end of file From 3303f7f11085b322e44326193a14e2e6a1966fad Mon Sep 17 00:00:00 2001 From: paul-hoang <96213640+paul-hoang@users.noreply.github.com> Date: Sat, 3 May 2025 08:37:18 +0000 Subject: [PATCH 4/4] add checks --- .../local-cse_call-without-effects.wast | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/test/lit/passes/local-cse_call-without-effects.wast b/test/lit/passes/local-cse_call-without-effects.wast index 02d3eac4907..15a08bb3e35 100644 --- a/test/lit/passes/local-cse_call-without-effects.wast +++ b/test/lit/passes/local-cse_call-without-effects.wast @@ -1,12 +1,42 @@ -;; RUN: foreach %s %t wasm-opt --local-cse --intrinsic-lowering -S -o - | filecheck %s +;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. +;; RUN: foreach %s %t wasm-opt --local-cse --intrinsic-lowering -all -S -o - | filecheck %s (module + ;; CHECK: (import "binaryen-intrinsics" "call.without.effects" (func $cwe-ii-i (type $1) (param i32 i32 funcref) (result i32))) (import "binaryen-intrinsics" "call.without.effects" (func $cwe-ii-i (param i32 i32 funcref) (result i32))) + ;; CHECK: (func $add (type $0) (param $0 i32) (param $1 i32) (result i32) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) (func $add (param $0 i32) (param $1 i32) (result i32) (i32.add (local.get $0) (local.get $1)) ) + ;; CHECK: (func $test (type $0) (param $0 i32) (param $1 i32) (result i32) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (local $3 i32) + ;; CHECK-NEXT: (local $4 i32) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (local.tee $4 + ;; CHECK-NEXT: (call $add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) (func $test (param $0 i32) (param $1 i32) (result i32) (local $2 i32) (local $3 i32) @@ -26,4 +56,4 @@ ) (return (i32.add (local.get $2) (local.get $3))) ) -) \ No newline at end of file +)