compiler.cfg.alias-analysis: write unit tests and fix redundant store elimination
							parent
							
								
									e436ae7314
								
							
						
					
					
						commit
						ce73031ec3
					
				| 
						 | 
					@ -0,0 +1,244 @@
 | 
				
			||||||
 | 
					USING: arrays compiler.cfg.alias-analysis compiler.cfg.instructions
 | 
				
			||||||
 | 
					compiler.cfg.registers compiler.cfg.debugger compiler.cfg.comparisons
 | 
				
			||||||
 | 
					cpu.architecture tools.test ;
 | 
				
			||||||
 | 
					IN: compiler.cfg.alias-analysis.tests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					! Redundant load elimination
 | 
				
			||||||
 | 
					[
 | 
				
			||||||
 | 
					    V{
 | 
				
			||||||
 | 
					        T{ ##peek f 0 D 0 }
 | 
				
			||||||
 | 
					        T{ ##slot-imm f 1 0 1 0 }
 | 
				
			||||||
 | 
					        T{ ##copy f 2 1 any-rep }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					] [
 | 
				
			||||||
 | 
					    V{
 | 
				
			||||||
 | 
					        T{ ##peek f 0 D 0 }
 | 
				
			||||||
 | 
					        T{ ##slot-imm f 1 0 1 0 }
 | 
				
			||||||
 | 
					        T{ ##slot-imm f 2 0 1 0 }
 | 
				
			||||||
 | 
					    } alias-analysis-step
 | 
				
			||||||
 | 
					] unit-test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					! Store-load forwarding
 | 
				
			||||||
 | 
					[
 | 
				
			||||||
 | 
					    V{
 | 
				
			||||||
 | 
					        T{ ##peek f 0 D 0 }
 | 
				
			||||||
 | 
					        T{ ##peek f 1 D 1 }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 1 0 1 0 }
 | 
				
			||||||
 | 
					        T{ ##copy f 2 1 any-rep }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					] [
 | 
				
			||||||
 | 
					    V{
 | 
				
			||||||
 | 
					        T{ ##peek f 0 D 0 }
 | 
				
			||||||
 | 
					        T{ ##peek f 1 D 1 }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 1 0 1 0 }
 | 
				
			||||||
 | 
					        T{ ##slot-imm f 2 0 1 0 }
 | 
				
			||||||
 | 
					    } alias-analysis-step
 | 
				
			||||||
 | 
					] unit-test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					! Dead store elimination
 | 
				
			||||||
 | 
					[
 | 
				
			||||||
 | 
					    V{
 | 
				
			||||||
 | 
					        T{ ##peek f 0 D 0 }
 | 
				
			||||||
 | 
					        T{ ##peek f 1 D 1 }
 | 
				
			||||||
 | 
					        T{ ##peek f 2 D 2 }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 2 0 1 0 }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					] [
 | 
				
			||||||
 | 
					    V{
 | 
				
			||||||
 | 
					        T{ ##peek f 0 D 0 }
 | 
				
			||||||
 | 
					        T{ ##peek f 1 D 1 }
 | 
				
			||||||
 | 
					        T{ ##peek f 2 D 2 }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 1 0 1 0 }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 2 0 1 0 }
 | 
				
			||||||
 | 
					    } alias-analysis-step
 | 
				
			||||||
 | 
					] unit-test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					! Redundant store elimination
 | 
				
			||||||
 | 
					[
 | 
				
			||||||
 | 
					    V{
 | 
				
			||||||
 | 
					        T{ ##peek f 0 D 0 }
 | 
				
			||||||
 | 
					        T{ ##slot-imm f 1 0 1 0 }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					] [
 | 
				
			||||||
 | 
					    V{
 | 
				
			||||||
 | 
					        T{ ##peek f 0 D 0 }
 | 
				
			||||||
 | 
					        T{ ##slot-imm f 1 0 1 0 }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 1 0 1 0 }
 | 
				
			||||||
 | 
					    } alias-analysis-step
 | 
				
			||||||
 | 
					] unit-test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[
 | 
				
			||||||
 | 
					    V{
 | 
				
			||||||
 | 
					        T{ ##peek f 0 D 0 }
 | 
				
			||||||
 | 
					        T{ ##slot-imm f 1 0 1 0 }
 | 
				
			||||||
 | 
					        T{ ##copy f 2 1 any-rep }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					] [
 | 
				
			||||||
 | 
					    V{
 | 
				
			||||||
 | 
					        T{ ##peek f 0 D 0 }
 | 
				
			||||||
 | 
					        T{ ##slot-imm f 1 0 1 0 }
 | 
				
			||||||
 | 
					        T{ ##copy f 2 1 any-rep }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 2 0 1 0 }
 | 
				
			||||||
 | 
					    } alias-analysis-step
 | 
				
			||||||
 | 
					] unit-test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					! Not a redundant load
 | 
				
			||||||
 | 
					[
 | 
				
			||||||
 | 
					    V{
 | 
				
			||||||
 | 
					        T{ ##peek f 0 D 0 }
 | 
				
			||||||
 | 
					        T{ ##peek f 1 D 1 }
 | 
				
			||||||
 | 
					        T{ ##slot-imm f 1 0 1 0 }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 0 1 1 0 }
 | 
				
			||||||
 | 
					        T{ ##slot-imm f 2 0 1 0 }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					] [
 | 
				
			||||||
 | 
					    V{
 | 
				
			||||||
 | 
					        T{ ##peek f 0 D 0 }
 | 
				
			||||||
 | 
					        T{ ##peek f 1 D 1 }
 | 
				
			||||||
 | 
					        T{ ##slot-imm f 1 0 1 0 }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 0 1 1 0 }
 | 
				
			||||||
 | 
					        T{ ##slot-imm f 2 0 1 0 }
 | 
				
			||||||
 | 
					    } alias-analysis-step
 | 
				
			||||||
 | 
					] unit-test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					! Not a redundant store
 | 
				
			||||||
 | 
					[
 | 
				
			||||||
 | 
					    V{
 | 
				
			||||||
 | 
					        T{ ##peek f 0 D 0 }
 | 
				
			||||||
 | 
					        T{ ##peek f 1 D 1 }
 | 
				
			||||||
 | 
					        T{ ##peek f 2 D 2 }
 | 
				
			||||||
 | 
					        T{ ##peek f 3 D 3 }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 2 1 1 0 }
 | 
				
			||||||
 | 
					        T{ ##slot-imm f 4 0 1 0 }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 3 1 1 0 }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					] [
 | 
				
			||||||
 | 
					    V{
 | 
				
			||||||
 | 
					        T{ ##peek f 0 D 0 }
 | 
				
			||||||
 | 
					        T{ ##peek f 1 D 1 }
 | 
				
			||||||
 | 
					        T{ ##peek f 2 D 2 }
 | 
				
			||||||
 | 
					        T{ ##peek f 3 D 3 }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 2 1 1 0 }
 | 
				
			||||||
 | 
					        T{ ##slot-imm f 4 0 1 0 }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 3 1 1 0 }
 | 
				
			||||||
 | 
					    } alias-analysis-step
 | 
				
			||||||
 | 
					] unit-test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					! There's a redundant load, but not a redundant store
 | 
				
			||||||
 | 
					[
 | 
				
			||||||
 | 
					    V{
 | 
				
			||||||
 | 
					        T{ ##peek f 0 D 0 }
 | 
				
			||||||
 | 
					        T{ ##peek f 1 D 1 }
 | 
				
			||||||
 | 
					        T{ ##peek f 2 D 2 }
 | 
				
			||||||
 | 
					        T{ ##peek f 3 D 3 }
 | 
				
			||||||
 | 
					        T{ ##slot-imm f 4 0 1 0 }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 2 0 1 0 }
 | 
				
			||||||
 | 
					        T{ ##slot f 5 0 3 0 0 }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 3 0 1 0 }
 | 
				
			||||||
 | 
					        T{ ##copy f 6 3 any-rep }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					] [
 | 
				
			||||||
 | 
					    V{
 | 
				
			||||||
 | 
					        T{ ##peek f 0 D 0 }
 | 
				
			||||||
 | 
					        T{ ##peek f 1 D 1 }
 | 
				
			||||||
 | 
					        T{ ##peek f 2 D 2 }
 | 
				
			||||||
 | 
					        T{ ##peek f 3 D 3 }
 | 
				
			||||||
 | 
					        T{ ##slot-imm f 4 0 1 0 }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 2 0 1 0 }
 | 
				
			||||||
 | 
					        T{ ##slot f 5 0 3 0 0 }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 3 0 1 0 }
 | 
				
			||||||
 | 
					        T{ ##slot-imm f 6 0 1 0 }
 | 
				
			||||||
 | 
					    } alias-analysis-step
 | 
				
			||||||
 | 
					] unit-test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					! Fresh allocations don't alias existing values
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					! Redundant load elimination
 | 
				
			||||||
 | 
					[
 | 
				
			||||||
 | 
					    V{
 | 
				
			||||||
 | 
					        T{ ##peek f 1 D 1 }
 | 
				
			||||||
 | 
					        T{ ##peek f 2 D 2 }
 | 
				
			||||||
 | 
					        T{ ##peek f 3 D 3 }
 | 
				
			||||||
 | 
					        T{ ##allot f 4 16 array }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 3 4 1 0 }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 2 1 1 0 }
 | 
				
			||||||
 | 
					        T{ ##copy f 5 3 any-rep }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					] [
 | 
				
			||||||
 | 
					    V{
 | 
				
			||||||
 | 
					        T{ ##peek f 1 D 1 }
 | 
				
			||||||
 | 
					        T{ ##peek f 2 D 2 }
 | 
				
			||||||
 | 
					        T{ ##peek f 3 D 3 }
 | 
				
			||||||
 | 
					        T{ ##allot f 4 16 array }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 3 4 1 0 }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 2 1 1 0 }
 | 
				
			||||||
 | 
					        T{ ##slot-imm f 5 4 1 0 }
 | 
				
			||||||
 | 
					    } alias-analysis-step
 | 
				
			||||||
 | 
					] unit-test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					! Redundant store elimination
 | 
				
			||||||
 | 
					[
 | 
				
			||||||
 | 
					    V{
 | 
				
			||||||
 | 
					        T{ ##peek f 1 D 1 }
 | 
				
			||||||
 | 
					        T{ ##peek f 2 D 2 }
 | 
				
			||||||
 | 
					        T{ ##peek f 3 D 3 }
 | 
				
			||||||
 | 
					        T{ ##allot f 4 16 array }
 | 
				
			||||||
 | 
					        T{ ##slot-imm f 5 1 1 0 }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 3 4 1 0 }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					] [
 | 
				
			||||||
 | 
					    V{
 | 
				
			||||||
 | 
					        T{ ##peek f 1 D 1 }
 | 
				
			||||||
 | 
					        T{ ##peek f 2 D 2 }
 | 
				
			||||||
 | 
					        T{ ##peek f 3 D 3 }
 | 
				
			||||||
 | 
					        T{ ##allot f 4 16 array }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 1 4 1 0 }
 | 
				
			||||||
 | 
					        T{ ##slot-imm f 5 1 1 0 }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 3 4 1 0 }
 | 
				
			||||||
 | 
					    } alias-analysis-step
 | 
				
			||||||
 | 
					] unit-test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					! Storing a new alias class into another object means that heap-ac
 | 
				
			||||||
 | 
					! can now alias the new ac
 | 
				
			||||||
 | 
					[
 | 
				
			||||||
 | 
					    V{
 | 
				
			||||||
 | 
					        T{ ##peek f 0 D 0 }
 | 
				
			||||||
 | 
					        T{ ##peek f 1 D 1 }
 | 
				
			||||||
 | 
					        T{ ##peek f 2 D 2 }
 | 
				
			||||||
 | 
					        T{ ##peek f 3 D 3 }
 | 
				
			||||||
 | 
					        T{ ##allot f 4 16 array }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 0 4 1 0 }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 4 2 1 0 }
 | 
				
			||||||
 | 
					        T{ ##slot-imm f 5 3 1 0 }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 1 5 1 0 }
 | 
				
			||||||
 | 
					        T{ ##slot-imm f 6 4 1 0 }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					] [
 | 
				
			||||||
 | 
					    V{
 | 
				
			||||||
 | 
					        T{ ##peek f 0 D 0 }
 | 
				
			||||||
 | 
					        T{ ##peek f 1 D 1 }
 | 
				
			||||||
 | 
					        T{ ##peek f 2 D 2 }
 | 
				
			||||||
 | 
					        T{ ##peek f 3 D 3 }
 | 
				
			||||||
 | 
					        T{ ##allot f 4 16 array }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 0 4 1 0 }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 4 2 1 0 }
 | 
				
			||||||
 | 
					        T{ ##slot-imm f 5 3 1 0 }
 | 
				
			||||||
 | 
					        T{ ##set-slot-imm f 1 5 1 0 }
 | 
				
			||||||
 | 
					        T{ ##slot-imm f 6 4 1 0 }
 | 
				
			||||||
 | 
					    } alias-analysis-step
 | 
				
			||||||
 | 
					] unit-test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					! Compares between objects which cannot alias are eliminated
 | 
				
			||||||
 | 
					[
 | 
				
			||||||
 | 
					    V{
 | 
				
			||||||
 | 
					        T{ ##peek f 0 D 0 }
 | 
				
			||||||
 | 
					        T{ ##allot f 1 16 array }
 | 
				
			||||||
 | 
					        T{ ##load-reference f 2 f }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					] [
 | 
				
			||||||
 | 
					    V{
 | 
				
			||||||
 | 
					        T{ ##peek f 0 D 0 }
 | 
				
			||||||
 | 
					        T{ ##allot f 1 16 array }
 | 
				
			||||||
 | 
					        T{ ##compare f 2 0 1 cc= }
 | 
				
			||||||
 | 
					    } alias-analysis-step
 | 
				
			||||||
 | 
					] unit-test
 | 
				
			||||||
| 
						 | 
					@ -7,7 +7,6 @@ compiler.cfg
 | 
				
			||||||
compiler.cfg.rpo
 | 
					compiler.cfg.rpo
 | 
				
			||||||
compiler.cfg.def-use
 | 
					compiler.cfg.def-use
 | 
				
			||||||
compiler.cfg.liveness
 | 
					compiler.cfg.liveness
 | 
				
			||||||
compiler.cfg.copy-prop
 | 
					 | 
				
			||||||
compiler.cfg.registers
 | 
					compiler.cfg.registers
 | 
				
			||||||
compiler.cfg.utilities
 | 
					compiler.cfg.utilities
 | 
				
			||||||
compiler.cfg.comparisons
 | 
					compiler.cfg.comparisons
 | 
				
			||||||
| 
						 | 
					@ -69,6 +68,14 @@ IN: compiler.cfg.alias-analysis
 | 
				
			||||||
! e = c
 | 
					! e = c
 | 
				
			||||||
! x[1] = c
 | 
					! x[1] = c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					! Local copy propagation
 | 
				
			||||||
 | 
					SYMBOL: copies
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					: resolve ( vreg -- vreg ) copies get ?at drop ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					: record-copy ( ##copy -- )
 | 
				
			||||||
 | 
					    [ src>> resolve ] [ dst>> ] bi copies get set-at ; inline
 | 
				
			||||||
 | 
					
 | 
				
			||||||
! Map vregs -> alias classes
 | 
					! Map vregs -> alias classes
 | 
				
			||||||
SYMBOL: vregs>acs
 | 
					SYMBOL: vregs>acs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -86,15 +93,10 @@ SYMBOL: acs>vregs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
: ac>vregs ( ac -- vregs ) acs>vregs get at ;
 | 
					: ac>vregs ( ac -- vregs ) acs>vregs get at ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GENERIC: aliases ( vreg -- vregs )
 | 
					: aliases ( vreg -- vregs )
 | 
				
			||||||
 | 
					 | 
				
			||||||
M: integer aliases
 | 
					 | 
				
			||||||
    #! All vregs which may contain the same value as vreg.
 | 
					    #! All vregs which may contain the same value as vreg.
 | 
				
			||||||
    vreg>ac ac>vregs ;
 | 
					    vreg>ac ac>vregs ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
M: word aliases
 | 
					 | 
				
			||||||
    1array ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
: each-alias ( vreg quot -- )
 | 
					: each-alias ( vreg quot -- )
 | 
				
			||||||
    [ aliases ] dip each ; inline
 | 
					    [ aliases ] dip each ; inline
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -259,7 +261,9 @@ M: ##read analyze-aliases*
 | 
				
			||||||
M: ##write analyze-aliases*
 | 
					M: ##write analyze-aliases*
 | 
				
			||||||
    dup
 | 
					    dup
 | 
				
			||||||
    [ src>> resolve ] [ insn-slot# ] [ insn-object ] tri
 | 
					    [ src>> resolve ] [ insn-slot# ] [ insn-object ] tri
 | 
				
			||||||
    [ remember-set-slot drop ] [ load-slot ] 3bi ;
 | 
					    3dup idempotent? [ 3drop ] [
 | 
				
			||||||
 | 
					        [ remember-set-slot drop ] [ load-slot ] 3bi
 | 
				
			||||||
 | 
					    ] if ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
M: ##copy analyze-aliases*
 | 
					M: ##copy analyze-aliases*
 | 
				
			||||||
    #! The output vreg gets the same alias class as the input
 | 
					    #! The output vreg gets the same alias class as the input
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue