| 
									
										
										
										
											2010-04-21 03:08:52 -04:00
										 |  |  | ! Copyright (C) 2008, 2010 Slava Pestov. | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							| 
									
										
										
										
											2008-12-06 10:16:29 -05:00
										 |  |  | USING: kernel math namespaces assocs hashtables sequences arrays | 
					
						
							| 
									
										
										
										
											2009-10-02 00:03:17 -04:00
										 |  |  | accessors words vectors combinators combinators.short-circuit | 
					
						
							| 
									
										
										
										
											2010-05-14 09:08:50 -04:00
										 |  |  | sets classes layouts fry locals cpu.architecture | 
					
						
							| 
									
										
										
										
											2009-10-02 00:03:17 -04:00
										 |  |  | compiler.cfg | 
					
						
							|  |  |  | compiler.cfg.rpo | 
					
						
							|  |  |  | compiler.cfg.def-use | 
					
						
							|  |  |  | compiler.cfg.liveness | 
					
						
							|  |  |  | compiler.cfg.registers | 
					
						
							| 
									
										
										
										
											2010-04-24 02:38:43 -04:00
										 |  |  | compiler.cfg.utilities | 
					
						
							| 
									
										
										
										
											2009-10-02 00:03:17 -04:00
										 |  |  | compiler.cfg.comparisons | 
					
						
							|  |  |  | compiler.cfg.instructions | 
					
						
							|  |  |  | compiler.cfg.representations.preferred ;
 | 
					
						
							| 
									
										
										
										
											2010-02-26 16:01:01 -05:00
										 |  |  | FROM: namespaces => set ;
 | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  | IN: compiler.cfg.alias-analysis | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-26 20:31:19 -04:00
										 |  |  | ! We try to eliminate redundant slot operations using some simple heuristics. | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  | ! 
 | 
					
						
							|  |  |  | ! All heap-allocated objects which are loaded from the stack, or | 
					
						
							|  |  |  | ! other object slots are pessimistically assumed to belong to | 
					
						
							|  |  |  | ! the same alias class. | 
					
						
							|  |  |  | !
 | 
					
						
							|  |  |  | ! Freshly-allocated objects get their own alias class. | 
					
						
							|  |  |  | !
 | 
					
						
							|  |  |  | ! Simple pseudo-C example showing load elimination: | 
					
						
							|  |  |  | ! 
 | 
					
						
							|  |  |  | ! int *x, *y, z: inputs | 
					
						
							|  |  |  | ! int a, b, c, d, e: locals | 
					
						
							|  |  |  | ! 
 | 
					
						
							|  |  |  | ! Before alias analysis: | 
					
						
							|  |  |  | !
 | 
					
						
							|  |  |  | ! a = x[2] | 
					
						
							|  |  |  | ! b = x[2] | 
					
						
							|  |  |  | ! c = x[3] | 
					
						
							|  |  |  | ! y[2] = z | 
					
						
							|  |  |  | ! d = x[2] | 
					
						
							|  |  |  | ! e = y[2] | 
					
						
							|  |  |  | ! f = x[3] | 
					
						
							|  |  |  | !
 | 
					
						
							|  |  |  | ! After alias analysis: | 
					
						
							|  |  |  | !
 | 
					
						
							|  |  |  | ! a = x[2] | 
					
						
							|  |  |  | ! b = a /* ELIMINATED */ | 
					
						
							|  |  |  | ! c = x[3] | 
					
						
							|  |  |  | ! y[2] = z | 
					
						
							|  |  |  | ! d = x[2] /* if x=y, d=z, if x!=y, d=b; NOT ELIMINATED */ | 
					
						
							|  |  |  | ! e = z /* ELIMINATED */ | 
					
						
							|  |  |  | ! f = c /* ELIMINATED */ | 
					
						
							|  |  |  | !
 | 
					
						
							|  |  |  | ! Simple pseudo-C example showing store elimination: | 
					
						
							|  |  |  | !
 | 
					
						
							|  |  |  | ! Before alias analysis: | 
					
						
							|  |  |  | !
 | 
					
						
							|  |  |  | ! x[0] = a | 
					
						
							|  |  |  | ! b = x[n] | 
					
						
							|  |  |  | ! x[0] = c | 
					
						
							|  |  |  | ! x[1] = d | 
					
						
							|  |  |  | ! e = x[0] | 
					
						
							|  |  |  | ! x[1] = c | 
					
						
							|  |  |  | !
 | 
					
						
							|  |  |  | ! After alias analysis: | 
					
						
							|  |  |  | !
 | 
					
						
							|  |  |  | ! x[0] = a /* dead if n = 0, live otherwise; NOT ELIMINATED */ | 
					
						
							|  |  |  | ! b = x[n] | 
					
						
							|  |  |  | ! x[0] = c | 
					
						
							|  |  |  | ! /* x[1] = d */  /* ELIMINATED */ | 
					
						
							|  |  |  | ! e = c | 
					
						
							|  |  |  | ! x[1] = c | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-30 18:17:52 -04:00
										 |  |  | ! Local copy propagation | 
					
						
							|  |  |  | SYMBOL: copies | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : resolve ( vreg -- vreg ) copies get ?at drop ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : record-copy ( ##copy -- )
 | 
					
						
							|  |  |  |     [ src>> resolve ] [ dst>> ] bi copies get set-at ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  | ! Map vregs -> alias classes | 
					
						
							|  |  |  | SYMBOL: vregs>acs | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-28 19:19:01 -04:00
										 |  |  | ERROR: vreg-ac-not-set vreg ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  | : 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. | 
					
						
							| 
									
										
										
										
											2009-05-28 19:19:01 -04:00
										 |  |  |     vregs>acs get ?at [ vreg-ac-not-set ] unless ;
 | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | ! Map alias classes -> sequence of vregs | 
					
						
							|  |  |  | SYMBOL: acs>vregs | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : ac>vregs ( ac -- vregs ) acs>vregs get at ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-30 18:17:52 -04:00
										 |  |  | : aliases ( vreg -- vregs )
 | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  |     #! All vregs which may contain the same value as vreg. | 
					
						
							|  |  |  |     vreg>ac ac>vregs ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : each-alias ( vreg quot -- )
 | 
					
						
							|  |  |  |     [ aliases ] dip each ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-03 18:20:28 -04:00
										 |  |  | : merge-acs ( vreg into -- )
 | 
					
						
							|  |  |  |     [ vreg>ac ] dip
 | 
					
						
							|  |  |  |     2dup eq? [ 2drop ] [ | 
					
						
							|  |  |  |         [ ac>vregs ] dip
 | 
					
						
							|  |  |  |         [ vregs>acs get '[ [ _ ] dip _ set-at ] each ] | 
					
						
							|  |  |  |         [ acs>vregs get at push-all ] | 
					
						
							|  |  |  |         2bi
 | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  | ! Map vregs -> slot# -> vreg | 
					
						
							|  |  |  | SYMBOL: live-slots | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 09:08:50 -04:00
										 |  |  | ! Maps vreg -> slot# -> insn# of last store or f | 
					
						
							|  |  |  | SYMBOL: recent-stores | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 09:08:50 -04:00
										 |  |  | ! A set of insn#s of dead stores | 
					
						
							|  |  |  | SYMBOL: dead-stores | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 09:08:50 -04:00
										 |  |  | : dead-store ( insn# -- ) dead-stores get adjoin ;
 | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 09:08:50 -04:00
										 |  |  | :: set-ac ( vreg ac -- )
 | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  |     #! Set alias class of newly-seen vreg. | 
					
						
							| 
									
										
										
										
											2010-05-14 09:08:50 -04:00
										 |  |  |     H{ } clone vreg recent-stores get set-at
 | 
					
						
							|  |  |  |     H{ } clone vreg live-slots get set-at
 | 
					
						
							|  |  |  |     ac vreg vregs>acs get set-at
 | 
					
						
							|  |  |  |     vreg ac acs>vregs get push-at ;
 | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : live-slot ( slot#/f vreg -- vreg' )
 | 
					
						
							|  |  |  |     #! If the slot number is unknown, we never reuse a previous | 
					
						
							|  |  |  |     #! value. | 
					
						
							|  |  |  |     over [ live-slots get at at ] [ 2drop f ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-28 19:19:01 -04:00
										 |  |  | ERROR: vreg-has-no-slots vreg ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  | : load-constant-slot ( value slot# vreg -- )
 | 
					
						
							| 
									
										
										
										
											2009-05-28 19:19:01 -04:00
										 |  |  |     live-slots get ?at [ vreg-has-no-slots ] unless set-at ;
 | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : load-slot ( value slot#/f vreg -- )
 | 
					
						
							|  |  |  |     over [ load-constant-slot ] [ 3drop ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : record-constant-slot ( slot# vreg -- )
 | 
					
						
							|  |  |  |     #! A load can potentially read every store of this slot# | 
					
						
							|  |  |  |     #! in that alias class. | 
					
						
							| 
									
										
										
										
											2010-05-14 09:08:50 -04:00
										 |  |  |     [ recent-stores get at delete-at ] with each-alias ;
 | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : record-computed-slot ( vreg -- )
 | 
					
						
							|  |  |  |     #! Computed load is like a load of every slot touched so far | 
					
						
							| 
									
										
										
										
											2010-05-14 09:08:50 -04:00
										 |  |  |     [ recent-stores get at clear-assoc ] each-alias ;
 | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 09:08:50 -04:00
										 |  |  | :: remember-slot ( value slot# vreg -- )
 | 
					
						
							|  |  |  |     slot# [ | 
					
						
							|  |  |  |         slot# vreg record-constant-slot | 
					
						
							|  |  |  |         value slot# vreg load-constant-slot | 
					
						
							|  |  |  |     ] [ vreg record-computed-slot ] if ;
 | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | SYMBOL: ac-counter | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : next-ac ( -- n )
 | 
					
						
							| 
									
										
										
										
											2009-08-13 20:21:44 -04:00
										 |  |  |     ac-counter [ dup 1 + ] change ;
 | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | ! 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 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : set-heap-ac ( vreg -- ) heap-ac get set-ac ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : set-new-ac ( vreg -- ) next-ac set-ac ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : kill-constant-set-slot ( slot# vreg -- )
 | 
					
						
							|  |  |  |     [ live-slots get at delete-at ] with each-alias ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 09:08:50 -04:00
										 |  |  | :: record-constant-set-slot ( insn# slot# vreg -- )
 | 
					
						
							|  |  |  |     vreg recent-stores get at :> recent-stores | 
					
						
							|  |  |  |     slot# recent-stores at [ dead-store ] when*
 | 
					
						
							|  |  |  |     insn# slot# recent-stores set-at ;
 | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 09:08:50 -04:00
										 |  |  | : kill-computed-set-slot ( vreg -- )
 | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  |     [ live-slots get at clear-assoc ] each-alias ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 09:08:50 -04:00
										 |  |  | :: remember-set-slot ( insn# slot# vreg -- )
 | 
					
						
							|  |  |  |     slot# [ | 
					
						
							|  |  |  |         insn# slot# vreg record-constant-set-slot | 
					
						
							|  |  |  |         slot# vreg kill-constant-set-slot | 
					
						
							|  |  |  |     ] [ vreg kill-computed-set-slot ] if ;
 | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-02 15:44:12 -04:00
										 |  |  | : init-alias-analysis ( -- )
 | 
					
						
							|  |  |  |     H{ } clone vregs>acs set
 | 
					
						
							|  |  |  |     H{ } clone acs>vregs set
 | 
					
						
							|  |  |  |     H{ } clone live-slots set
 | 
					
						
							|  |  |  |     H{ } clone copies set
 | 
					
						
							|  |  |  |     H{ } clone recent-stores set
 | 
					
						
							|  |  |  |     HS{ } clone dead-stores set
 | 
					
						
							|  |  |  |     0 ac-counter set ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  | GENERIC: insn-slot# ( insn -- slot#/f )
 | 
					
						
							|  |  |  | GENERIC: insn-object ( insn -- vreg )
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-21 03:08:52 -04:00
										 |  |  | M: ##slot insn-slot# drop f ;
 | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  | M: ##slot-imm insn-slot# slot>> ;
 | 
					
						
							| 
									
										
										
										
											2010-04-21 03:08:52 -04:00
										 |  |  | M: ##set-slot insn-slot# drop f ;
 | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  | M: ##set-slot-imm insn-slot# slot>> ;
 | 
					
						
							| 
									
										
										
										
											2008-12-06 10:16:29 -05:00
										 |  |  | M: ##alien-global insn-slot# [ library>> ] [ symbol>> ] bi 2array ;
 | 
					
						
							| 
									
										
										
										
											2010-04-01 20:06:18 -04:00
										 |  |  | M: ##vm-field insn-slot# offset>> ;
 | 
					
						
							|  |  |  | M: ##set-vm-field insn-slot# offset>> ;
 | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | M: ##slot insn-object obj>> resolve ;
 | 
					
						
							|  |  |  | M: ##slot-imm insn-object obj>> resolve ;
 | 
					
						
							|  |  |  | M: ##set-slot insn-object obj>> resolve ;
 | 
					
						
							|  |  |  | M: ##set-slot-imm insn-object obj>> resolve ;
 | 
					
						
							| 
									
										
										
										
											2008-12-06 10:16:29 -05:00
										 |  |  | M: ##alien-global insn-object drop \ ##alien-global ;
 | 
					
						
							| 
									
										
										
										
											2010-04-01 20:06:18 -04:00
										 |  |  | M: ##vm-field insn-object drop \ ##vm-field ;
 | 
					
						
							|  |  |  | M: ##set-vm-field insn-object drop \ ##vm-field ;
 | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 09:08:50 -04:00
										 |  |  | GENERIC: analyze-aliases ( insn -- insn' )
 | 
					
						
							| 
									
										
										
										
											2009-10-02 00:03:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 09:08:50 -04:00
										 |  |  | M: insn analyze-aliases ;
 | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 09:08:50 -04:00
										 |  |  | M: vreg-insn analyze-aliases | 
					
						
							| 
									
										
										
										
											2009-10-02 00:03:17 -04:00
										 |  |  |     ! If an instruction defines a value with a non-integer | 
					
						
							|  |  |  |     ! representation it means that the value will be boxed | 
					
						
							|  |  |  |     ! anywhere its used as a tagged pointer. Boxing allocates | 
					
						
							|  |  |  |     ! a new value, except boxing instructions haven't been | 
					
						
							|  |  |  |     ! inserted yet. | 
					
						
							|  |  |  |     dup defs-vreg [ | 
					
						
							| 
									
										
										
										
											2010-04-19 15:05:55 -04:00
										 |  |  |         over defs-vreg-rep { int-rep tagged-rep } member?
 | 
					
						
							| 
									
										
										
										
											2009-10-02 00:03:17 -04:00
										 |  |  |         [ set-heap-ac ] [ set-new-ac ] if
 | 
					
						
							|  |  |  |     ] when* ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 09:08:50 -04:00
										 |  |  | M: ##phi analyze-aliases | 
					
						
							| 
									
										
										
										
											2009-10-02 00:03:17 -04:00
										 |  |  |     dup defs-vreg set-heap-ac ;
 | 
					
						
							| 
									
										
										
										
											2009-09-02 07:22:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 09:08:50 -04:00
										 |  |  | M: ##allocation analyze-aliases | 
					
						
							| 
									
										
										
										
											2008-11-03 02:52:55 -05:00
										 |  |  |     #! A freshly allocated object is distinct from any other | 
					
						
							|  |  |  |     #! object. | 
					
						
							|  |  |  |     dup dst>> set-new-ac ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 09:08:50 -04:00
										 |  |  | M: ##box-displaced-alien analyze-aliases | 
					
						
							| 
									
										
										
										
											2010-05-13 01:46:58 -04:00
										 |  |  |     [ call-next-method ] | 
					
						
							|  |  |  |     [ base>> heap-ac get merge-acs ] bi ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 09:08:50 -04:00
										 |  |  | M: ##read analyze-aliases | 
					
						
							| 
									
										
										
										
											2009-05-29 02:39:14 -04:00
										 |  |  |     call-next-method | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  |     dup [ dst>> ] [ insn-slot# ] [ insn-object ] tri
 | 
					
						
							| 
									
										
										
										
											2010-04-24 02:38:43 -04:00
										 |  |  |     2dup live-slot dup
 | 
					
						
							| 
									
										
										
										
											2010-05-14 09:08:50 -04:00
										 |  |  |     [ 2nip <copy> analyze-aliases nip ] | 
					
						
							| 
									
										
										
										
											2010-04-24 02:38:43 -04:00
										 |  |  |     [ drop remember-slot ] | 
					
						
							|  |  |  |     if ;
 | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : idempotent? ( value slot#/f vreg -- ? )
 | 
					
						
							|  |  |  |     #! Are we storing a value back to the same slot it was read | 
					
						
							|  |  |  |     #! from? | 
					
						
							|  |  |  |     live-slot = ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 09:08:50 -04:00
										 |  |  | M:: ##write analyze-aliases ( insn -- insn )
 | 
					
						
							|  |  |  |     insn src>> resolve :> src | 
					
						
							|  |  |  |     insn insn-slot# :> slot# | 
					
						
							|  |  |  |     insn insn-object :> vreg | 
					
						
							|  |  |  |     insn insn#>> :> insn# | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     src slot# vreg idempotent? [ insn# dead-store ] [ | 
					
						
							|  |  |  |         src heap-ac get merge-acs | 
					
						
							|  |  |  |         insn insn#>> slot# vreg remember-set-slot | 
					
						
							|  |  |  |         src slot# vreg load-slot | 
					
						
							|  |  |  |     ] if
 | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 09:08:50 -04:00
										 |  |  |     insn ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: ##copy analyze-aliases | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  |     #! The output vreg gets the same alias class as the input | 
					
						
							|  |  |  |     #! vreg, since they both contain the same value. | 
					
						
							|  |  |  |     dup record-copy ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-02 00:03:17 -04:00
										 |  |  | : useless-compare? ( insn -- ? )
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         [ cc>> cc= eq? ] | 
					
						
							| 
									
										
										
										
											2009-10-02 00:54:19 -04:00
										 |  |  |         [ [ src1>> ] [ src2>> ] bi [ resolve vreg>ac ] bi@ = not ] | 
					
						
							| 
									
										
										
										
											2009-10-02 00:03:17 -04:00
										 |  |  |     } 1&& ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 09:08:50 -04:00
										 |  |  | M: ##compare analyze-aliases | 
					
						
							| 
									
										
										
										
											2009-10-02 00:20:05 -04:00
										 |  |  |     call-next-method | 
					
						
							| 
									
										
										
										
											2009-10-02 00:03:17 -04:00
										 |  |  |     dup useless-compare? [ | 
					
						
							| 
									
										
										
										
											2010-04-21 03:08:52 -04:00
										 |  |  |         dst>> f \ ##load-reference new-insn | 
					
						
							| 
									
										
										
										
											2010-05-14 09:08:50 -04:00
										 |  |  |         analyze-aliases | 
					
						
							| 
									
										
										
										
											2009-10-02 00:03:17 -04:00
										 |  |  |     ] when ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 09:08:50 -04:00
										 |  |  | : reset-alias-analysis ( -- )
 | 
					
						
							|  |  |  |     recent-stores get clear-assoc
 | 
					
						
							|  |  |  |     vregs>acs get clear-assoc
 | 
					
						
							|  |  |  |     acs>vregs get clear-assoc
 | 
					
						
							|  |  |  |     live-slots get clear-assoc
 | 
					
						
							|  |  |  |     copies get clear-assoc
 | 
					
						
							|  |  |  |     dead-stores get table>> clear-assoc
 | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 09:08:50 -04:00
										 |  |  |     next-ac heap-ac set
 | 
					
						
							|  |  |  |     \ ##vm-field set-new-ac | 
					
						
							|  |  |  |     \ ##alien-global set-new-ac ;
 | 
					
						
							| 
									
										
										
										
											2008-10-22 19:37:47 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-02 15:44:12 -04:00
										 |  |  | M: factor-call-insn analyze-aliases | 
					
						
							|  |  |  |     heap-ac get ac>vregs [ | 
					
						
							|  |  |  |         [ live-slots get at clear-assoc ] | 
					
						
							|  |  |  |         [ recent-stores get at clear-assoc ] bi
 | 
					
						
							|  |  |  |     ] each ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | GENERIC: eliminate-dead-stores ( insn -- ? )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: ##set-slot-imm eliminate-dead-stores | 
					
						
							|  |  |  |     insn#>> dead-stores get in? not ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: insn eliminate-dead-stores drop t ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-26 20:56:56 -04:00
										 |  |  | : alias-analysis-step ( insns -- insns' )
 | 
					
						
							| 
									
										
										
										
											2010-05-14 09:08:50 -04:00
										 |  |  |     reset-alias-analysis | 
					
						
							|  |  |  |     [ local-live-in [ set-heap-ac ] each ] | 
					
						
							|  |  |  |     [ 0 [ [ insn#<< ] [ drop 1 + ] 2bi ] reduce drop ] | 
					
						
							|  |  |  |     [ [ analyze-aliases ] map! [ eliminate-dead-stores ] filter! ] tri ;
 | 
					
						
							| 
									
										
										
										
											2009-05-26 20:31:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-30 18:55:20 -04:00
										 |  |  | : alias-analysis ( cfg -- cfg )
 | 
					
						
							| 
									
										
										
										
											2010-05-14 09:08:50 -04:00
										 |  |  |     init-alias-analysis | 
					
						
							| 
									
										
										
										
											2010-04-30 18:55:20 -04:00
										 |  |  |     dup [ alias-analysis-step ] simple-optimization ;
 |