Strongly connected components could be a cool pass to implement, it handles constant folding (seems like most passes have some support for constant folding?) and certain kinds of common subexpression elimination. The paper I'm mainly looking at is https://www.cs.rice.edu/~keith/Publications/SCCVN.pdf The algorithm (in short) is for all SSA names i VN [i] <- T repeat done <- TRUE for all blocks b in reverse postorder for all definitions x in b temp <- lookup(x:op; VN[x[1]]; VN[x[2]]; x) if VN[x] != temp done <- FALSE VN[x] <- temp Remove all entries from the hash table until done Where lookup computes a unique hash for x, in C I guess it could just be op VN1 VN2 32 64 64 The lookup returns the name of the expression if found, otherwise adds the name x to the map. The paper extends this by adding a map where each SSA name also uses the constant propagation lattice (TODO: can we use a range lattice? or is that too much in one pass?) To make sure a + b and b + a are the same, I guess each expression node should sort its inputs. SCC is in the name, but I wonder if being strongly connected is necessary for the algorithm or if it only speeds up the computation as doing it in that order ensures values are 'final' when the block (or block group) is finished, whereas otherwise the whole graph seems to be iterated on excessively?