| 
									
										
										
										
											2010-04-19 15:05:55 -04:00
										 |  |  | ! Copyright (C) 2010 Slava Pestov. | 
					
						
							|  |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							|  |  |  | USING: accessors arrays assocs combinators | 
					
						
							| 
									
										
										
										
											2010-04-21 03:08:52 -04:00
										 |  |  | combinators.short-circuit layouts kernel locals make math | 
					
						
							|  |  |  | namespaces sequences | 
					
						
							|  |  |  | compiler.cfg.instructions | 
					
						
							|  |  |  | compiler.cfg.registers | 
					
						
							|  |  |  | compiler.cfg.renaming.functor | 
					
						
							| 
									
										
										
										
											2010-04-19 15:05:55 -04:00
										 |  |  | compiler.cfg.representations.conversion | 
					
						
							| 
									
										
										
										
											2010-04-21 03:08:52 -04:00
										 |  |  | compiler.cfg.representations.preferred | 
					
						
							|  |  |  | compiler.cfg.rpo | 
					
						
							|  |  |  | compiler.cfg.utilities | 
					
						
							|  |  |  | cpu.architecture ;
 | 
					
						
							| 
									
										
										
										
											2010-04-19 15:05:55 -04:00
										 |  |  | IN: compiler.cfg.representations.rewrite | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ! Insert conversions. This introduces new temporaries, so we need | 
					
						
							|  |  |  | ! to rename opearands too. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ! Mapping from vreg,rep pairs to vregs | 
					
						
							|  |  |  | SYMBOL: alternatives | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-23 04:18:31 -04:00
										 |  |  | :: (emit-def-conversion) ( dst preferred required -- new-dst' )
 | 
					
						
							| 
									
										
										
										
											2010-04-19 15:05:55 -04:00
										 |  |  |     ! If an instruction defines a register with representation 'required', | 
					
						
							|  |  |  |     ! but the register has preferred representation 'preferred', then | 
					
						
							|  |  |  |     ! we rename the instruction's definition to a new register, which | 
					
						
							|  |  |  |     ! becomes the input of a conversion instruction. | 
					
						
							|  |  |  |     dst required next-vreg-rep [ preferred required emit-conversion ] keep ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-23 04:18:31 -04:00
										 |  |  | :: (emit-use-conversion) ( src preferred required -- new-src' )
 | 
					
						
							| 
									
										
										
										
											2010-04-19 15:05:55 -04:00
										 |  |  |     ! If an instruction uses a register with representation 'required', | 
					
						
							|  |  |  |     ! but the register has preferred representation 'preferred', then | 
					
						
							|  |  |  |     ! we rename the instruction's input to a new register, which | 
					
						
							|  |  |  |     ! becomes the output of a conversion instruction. | 
					
						
							|  |  |  |     preferred required eq? [ src ] [ | 
					
						
							|  |  |  |         src required alternatives get [ | 
					
						
							|  |  |  |             required next-vreg-rep :> new-src | 
					
						
							|  |  |  |             [ new-src ] 2dip preferred emit-conversion | 
					
						
							|  |  |  |             new-src | 
					
						
							|  |  |  |         ] 2cache
 | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SYMBOLS: renaming-set needs-renaming? ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : init-renaming-set ( -- )
 | 
					
						
							|  |  |  |     needs-renaming? off
 | 
					
						
							| 
									
										
										
										
											2010-04-23 04:18:31 -04:00
										 |  |  |     renaming-set get delete-all ;
 | 
					
						
							| 
									
										
										
										
											2010-04-19 15:05:55 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : no-renaming ( vreg -- )
 | 
					
						
							|  |  |  |     dup 2array renaming-set get push ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : record-renaming ( from to -- )
 | 
					
						
							|  |  |  |     2array renaming-set get push needs-renaming? on ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :: (compute-renaming-set) ( vreg required quot: ( vreg preferred required -- new-vreg ) -- )
 | 
					
						
							|  |  |  |     vreg rep-of :> preferred | 
					
						
							|  |  |  |     preferred required eq?
 | 
					
						
							|  |  |  |     [ vreg no-renaming ] | 
					
						
							|  |  |  |     [ vreg vreg preferred required quot call record-renaming ] if ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-23 04:18:31 -04:00
										 |  |  | : emit-use-conversion ( insn -- )
 | 
					
						
							|  |  |  |     [ [ (emit-use-conversion) ] (compute-renaming-set) ] each-use-rep ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-24 20:05:52 -04:00
										 |  |  | : no-use-conversion ( insn -- )
 | 
					
						
							|  |  |  |     [ drop no-renaming ] each-use-rep ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-23 04:18:31 -04:00
										 |  |  | : emit-def-conversion ( insn -- )
 | 
					
						
							|  |  |  |     [ [ (emit-def-conversion) ] (compute-renaming-set) ] each-def-rep ;
 | 
					
						
							| 
									
										
										
										
											2010-04-19 15:05:55 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-24 20:05:52 -04:00
										 |  |  | : no-def-conversion ( insn -- )
 | 
					
						
							|  |  |  |     [ drop no-renaming ] each-def-rep ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-19 15:05:55 -04:00
										 |  |  | : converted-value ( vreg -- vreg' )
 | 
					
						
							|  |  |  |     renaming-set get pop first2 [ assert= ] dip ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | RENAMING: convert [ converted-value ] [ converted-value ] [ ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : perform-renaming ( insn -- )
 | 
					
						
							|  |  |  |     needs-renaming? get [ | 
					
						
							|  |  |  |         renaming-set get reverse! drop
 | 
					
						
							|  |  |  |         [ convert-insn-uses ] [ convert-insn-defs ] bi
 | 
					
						
							|  |  |  |         renaming-set get length 0 assert=
 | 
					
						
							|  |  |  |     ] [ drop ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | GENERIC: conversions-for-insn ( insn -- )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: ##phi conversions-for-insn , ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-25 05:13:04 -04:00
										 |  |  | M: ##copy conversions-for-insn , ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-19 15:05:55 -04:00
										 |  |  | M: insn conversions-for-insn , ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 18:18:29 -04:00
										 |  |  | : conversions-for-block ( insns -- insns )
 | 
					
						
							| 
									
										
										
										
											2010-05-09 21:36:52 -04:00
										 |  |  |     [ | 
					
						
							| 
									
										
										
										
											2010-05-14 18:18:29 -04:00
										 |  |  |         alternatives get clear-assoc
 | 
					
						
							|  |  |  |         [ conversions-for-insn ] each
 | 
					
						
							|  |  |  |     ] V{ } make ;
 | 
					
						
							| 
									
										
										
										
											2010-04-19 15:05:55 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : insert-conversions ( cfg -- )
 | 
					
						
							| 
									
										
										
										
											2010-05-09 21:36:52 -04:00
										 |  |  |     H{ } clone alternatives set
 | 
					
						
							| 
									
										
										
										
											2010-04-23 04:18:31 -04:00
										 |  |  |     V{ } clone renaming-set set
 | 
					
						
							| 
									
										
										
										
											2010-05-14 18:18:29 -04:00
										 |  |  |     [ conversions-for-block ] simple-optimization ;
 |