Skip to content

ConstraintAnalysis: Properly handle local changes#8878

Open
kripken wants to merge 19 commits into
WebAssembly:mainfrom
kripken:constraint.3b
Open

ConstraintAnalysis: Properly handle local changes#8878
kripken wants to merge 19 commits into
WebAssembly:mainfrom
kripken:constraint.3b

Conversation

@kripken

@kripken kripken commented Jun 30, 2026

Copy link
Copy Markdown
Member

Track references of a local among the constraints of the rest. When a local
is updated, remove its stale references (claims about its old value no
longer hold).

Also, formalize how we represent info: when we see x == y, we now store
that on both x and y, ensuring a single place where we can find all
constraints about a local.

@kripken kripken requested a review from tlively June 30, 2026 19:58
@kripken kripken requested a review from a team as a code owner June 30, 2026 19:58
Comment thread src/ir/abstract.h

inline bool isRelationalSymmetric(Op op) { return op == Eq || op == Ne; }

inline bool isRelationalAntisymmetric(Op op) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm getting weirdly caught up on whether the *-or-equal variants count as antisymmetric. Taking <= as an example, antisymmetry means that for all x and y we have x <= y /\ y <= x ==> x == y. If the domain is integer or real values, that's certainly true, but my mental model is that the domain is terms, in which case this is not true. We can easily have distinct variables x and y where both x <= y and y <= x. In that case we know the values of x and y are equal, but x is not identical to y.

Comment thread src/ir/constraint.cpp
Comment on lines +306 to +317
if (flip) {
// Build a flipped constraint, referring to index.
auto otherIndex = std::get<Index>(actual.term);
actual.term = Term{index};
index = otherIndex;
if (Abstract::isRelationalAntisymmetric(actual.op)) {
actual.op = Abstract::negateRelational(actual.op);
} else {
// All we support for now are symmetric and antisymmetric operations.
assert(Abstract::isRelationalSymmetric(actual.op));
}
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we pull this flip operation out into a helper function, maybe on LocalConstraint?

Comment thread src/ir/constraint.h
Comment on lines +209 to +211
// Cross-local constraints (like x == y) are duplicated, that is, they appear in
// the constraints for both x and y. This makes things simple by having all
// constraints related to a local in the same place.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of storing each variable-variable constraint in both directions (which uses the limited space in our bounded conjunctions), we could arbitrarily just store it in one direction (possibly by choosing the variable with the most remaining free space for constraints), then on lookup rely on refs to tell us where else we might find relevant constraints. But then I guess you wouldn't have all the relevant constraints packaged up as a single bounded conjunction :/

Comment thread src/ir/constraint.h
Comment on lines +231 to +232
// If we can prove nothing, we should have removed it from the map.
assert(!constraints.provesNothing());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can also assert that it's not a contradiction, right?

constraints.set(set->index, Constraint{Abstract::Eq, {value}});
} else if (auto* get = set->value->dynCast<LocalGet>()) {
// Apply a constraint to this local.
constraints.set(set->index, Constraint{Abstract::Eq, {get->index}});

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also look up everything we previously knew about get->index and apply it to set->index. This would help optimize situations where we need to know transitive constraints.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants