You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
5. **Fingerprint** — SHA-256 of canonical IR string
193
+
194
+
### Scalar Evolution (SCEV) Engine
195
+
196
+
The SCEV framework (`scev.go`, 746 LOC) solves the "loop equivalence problem"—proving that syntactically different loops compute the same sequence of values.
197
+
198
+
**Core Abstraction: Add Recurrences**
199
+
200
+
An induction variable is represented as $\{Start, +, Step\}_L$, meaning at iteration $k$ the value is:
201
+
202
+
$$Val(k) = Start + (Step \times k)$$
203
+
204
+
This representation is closed under affine transformations:
The result: semantically equivalent code produces identical fingerprints.
238
+
### Canonicalization Engine
186
239
187
-
### Scalar Evolution (SCEV) Analysis
240
+
The canonicalizer (`canonicalizer.go`, 1162 LOC) transforms SSA into a deterministic string representation via five phases:
188
241
189
-
Standard hashing is brittle—changing `for i := 0` to `for range` breaks the hash. `sfw` solves this with an SCEV engine (`scev.go`) that algebraically solves loops:
242
+
**Phase 1: Loop & SCEV Analysis**
243
+
```go
244
+
c.loopInfo = DetectLoops(fn)
245
+
AnalyzeSCEV(c.loopInfo)
246
+
```
247
+
248
+
**Phase 2: Semantic Normalization**
249
+
-**Invariant Hoisting**: Pure calls like `len(s)` are virtually moved to pre-header
250
+
-**IV Virtualization**: Phi nodes for IVs are replaced with SCEV notation `{0, +, 1}`
251
+
-**Derived IV Propagation**: Expressions like `i*4` become `{0, +, 4}` in output
252
+
253
+
**Phase 3: Register Renaming**
254
+
```
255
+
Parameters: p0, p1, p2, ...
256
+
Free Variables: fv0, fv1, ...
257
+
Instructions: v0, v1, v2, ... (DFS order)
258
+
```
259
+
260
+
**Phase 4: Deterministic Block Ordering**
261
+
262
+
Blocks are traversed in dominance-respecting DFS order, ensuring identical output regardless of SSA construction order. Successor ordering is normalized:
263
+
-`>=` branches are rewritten to `<` with swapped successors
264
+
-`>` branches are rewritten to `<=` with swapped successors
When logic *does* change (e.g., architectural refactors), fingerprint comparison fails. The Zipper algorithm (`zipper.go`) takes two SSA graphs and "zips" them together starting from function parameters:
276
+
The Zipper (`zipper.go`, 568 LOC) computes a semantic diff between two functions—what actually changed in behavior, ignoring cosmetic differences.
0 commit comments