Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
5485081
go
kripken Feb 17, 2026
de7223c
fix
kripken Feb 18, 2026
22f4de9
Merge remote-tracking branch 'origin/main' into no.jscall.merge
kripken Feb 18, 2026
bbf85b9
fix
kripken Feb 18, 2026
18565f9
finish
kripken Feb 18, 2026
df4c8aa
almost
kripken Feb 19, 2026
0b326e2
go
kripken Feb 19, 2026
a95d3ed
fmt
kripken Feb 19, 2026
d66a33a
comment
kripken Feb 19, 2026
881576b
more
kripken Feb 19, 2026
48d8384
more
kripken Feb 19, 2026
c769ed0
more
kripken Feb 19, 2026
bcd5dac
go
kripken Feb 19, 2026
ef44cc2
form
kripken Feb 19, 2026
148fa86
more
kripken Feb 19, 2026
80ad047
more
kripken Feb 20, 2026
6493931
test
kripken Feb 20, 2026
af34e7b
works
kripken Feb 20, 2026
97a7a52
work
kripken Feb 20, 2026
9b1a94c
work
kripken Feb 20, 2026
b38290d
work
kripken Feb 20, 2026
001edbe
work
kripken Feb 20, 2026
868a60c
work
kripken Feb 20, 2026
d446f0c
work
kripken Feb 20, 2026
357e519
fix
kripken Feb 20, 2026
314443f
format
kripken Feb 20, 2026
0f429e4
work
kripken Feb 20, 2026
65f10b3
work
kripken Feb 20, 2026
f791aa6
work
kripken Feb 20, 2026
ed0dc57
fix
kripken Feb 20, 2026
ef4d2f0
format
kripken Feb 20, 2026
fb1df27
finish
kripken Feb 20, 2026
9f1fc53
simplify
kripken Feb 20, 2026
2f2d043
handle a single annotation + testing
kripken Feb 21, 2026
a9b5a7f
:Merge remote-tracking branch 'origin/main' into no.jscall.merge
kripken Feb 23, 2026
5c8f0f5
Merge branch 'main' into idempotent
kripken Feb 23, 2026
31431a8
prep for idem
kripken Feb 23, 2026
f3f78ae
nicer
kripken Feb 23, 2026
ff7dfa7
Merge remote-tracking branch 'origin/main' into no.jscall.merge
kripken Feb 23, 2026
8367efa
Merge remote-tracking branch 'myself/idempotent' into no.jscall.merge
kripken Feb 23, 2026
5db400c
const
kripken Feb 23, 2026
d56b442
finish
kripken Feb 23, 2026
14ac58b
erg
kripken Feb 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions scripts/test/fuzzing.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
'strip-toolchain-annotations-func.wast',
'idempotent.wast',
'optimize-instructions_idempotent.wast',
'duplicate-function-elimination_annotations.wast',
# Not fully implemented.
'waitqueue.wast',
]
Expand Down
15 changes: 14 additions & 1 deletion src/ir/function-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#ifndef wasm_ir_function_h
#define wasm_ir_function_h

#include "ir/intrinsics.h"
#include "ir/utils.h"
#include "wasm.h"

Expand All @@ -37,16 +38,28 @@ inline bool equal(Function* left, Function* right) {
return false;
}
}

// We could in principle compare metadata here, but intentionally do not, as
// for optimization purposes we do want to e.g. merge functions that differ
// only in metadata (following LLVM's example). If we have a non-optimization
// reason for comparing metadata here then we could add a flag for it.
// reason for comparing metadata here then we could add a flag for it. We do,
// however, compare metadata that changes semantics (not debug info, but
// things like jsCalled). We do that check conservatively, erasing the non-
// semantic-altering ones and then comparing (so that new annotations
auto leftAnnotations = Intrinsics::getAnnotations(left);
auto rightAnnotations = Intrinsics::getAnnotations(right);
if (!leftAnnotations.equalOnSemanticsAltering(rightAnnotations)) {
return false;
}

if (left->imported() && right->imported()) {
return true;
}
if (left->imported() || right->imported()) {
return false;
}
// TODO: Compare expression-level annotations like removableIfUnused, not just
// function-level.
return ExpressionAnalyzer::equal(left->body, right->body);
}

Expand Down
14 changes: 12 additions & 2 deletions src/wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -2265,8 +2265,18 @@ struct CodeAnnotation {
bool idempotent = false;

bool operator==(const CodeAnnotation& other) const {
return branchLikely == other.branchLikely && inline_ == other.inline_ &&
removableIfUnused == other.removableIfUnused &&
return equalOnSemanticsPreserving(other) && equalOnSemanticsAltering(other);
}

// Compares only true hints, that preserve semantics and do not change
// behavior in the optimizer.
bool equalOnSemanticsPreserving(const CodeAnnotation& other) const {
return branchLikely == other.branchLikely && inline_ == other.inline_;
}

// Compares annotations that *do* alter semantics.
bool equalOnSemanticsAltering(const CodeAnnotation& other) const {
return removableIfUnused == other.removableIfUnused &&
jsCalled == other.jsCalled && idempotent == other.idempotent;
}
};
Expand Down
Loading
Loading