 ! Map vregs -> alias classes
 SYMBOL: vregs>acs
 
-ERROR: vreg-ac-not-set vreg ;
+! Map alias classes -> sequence of vregs
+SYMBOL: acs>vregs
+
+! Alias class for objects which are loaded from the data stack
+! or other object slots. We pessimistically assume that they
+! can all alias each other.
+SYMBOL: heap-ac
+
+: ac>vregs ( ac -- vregs )
+    acs>vregs get [ drop V{ } clone ] cache ;
 
 : vreg>ac ( vreg -- ac )
     #! Only vregs produced by ##allot, ##peek and ##slot can
     #! ever be used as valid inputs to ##slot and ##set-slot,
     #! so we assert this fact by not giving alias classes to
     #! other vregs.
-    vregs>acs get ?at [ vreg-ac-not-set ] unless ;
-
-! Map alias classes -> sequence of vregs
-SYMBOL: acs>vregs
-
-: ac>vregs ( ac -- vregs ) acs>vregs get at ;
+    vregs>acs get [ heap-ac get [ ac>vregs push ] keep ] cache ;
 
 : aliases ( vreg -- vregs )
     #! All vregs which may contain the same value as vreg.

    ! inserted yet.
    dup [
        { int-rep tagged-rep } member?
        [ set-heap-ac ] [ set-new-ac ] if
    ] each-def-rep ;

M: vreg-insn analyze-aliases
    def-acs ;

M: ##phi analyze-aliases
    dup dst>> set-heap-ac ;

M: ##allocation analyze-aliases
    #! A freshly allocated object is distinct from any other


: alias-analysis-step ( insns -- insns' )
    reset-alias-analysis
    [ 0 [ [ insn#<< ] [ drop 1 + ] 2bi ] reduce drop ]
    [ [ analyze-aliases ] map! [ eliminate-dead-stores ] filter! ] bi ;

: alias-analysis ( cfg -- cfg )
    init-alias-analysis
