Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] View of /sml/trunk/src/MLRISC/instructions/shuffle.sml
ViewVC logotype

View of /sml/trunk/src/MLRISC/instructions/shuffle.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 411 - (download) (annotate)
Fri Sep 3 00:25:03 1999 UTC (20 years ago) by monnier
Original Path: sml/branches/SMLNJ/src/MLRISC/instructions/shuffle.sml
File size: 1959 byte(s)
version 110.19
(* shuffle.sml -- implements the parallel copy instruction as a sequence
 *		of moves. 
 *
 * COPYRIGHT (c) 1996 Bell Laboratories.
 *
 *)


functor Shuffle(I : INSTRUCTIONS) :
  sig
    val shuffle : 
      {mvInstr : {dst:I.ea, src:I.ea} -> I.instruction list,
       ea : int -> I.ea} 
      ->
	{regmap: int -> int,
	 tmp : I.ea option,
	 dst : int list,
	 src : int list} 
	-> I.instruction list
  end = 
struct
  datatype reg = REG of int | TEMP
  fun equal (REG r1, REG r2) = r1 = r2
    | equal (TEMP, TEMP) = true
    | equal _ = false

  fun shuffle{mvInstr, ea} {regmap, tmp, dst, src} = let
    val mv = rev o mvInstr
    fun opnd (REG dst) = ea dst
      | opnd TEMP = Option.valOf tmp

    (* perform unconstrained moves *)
    fun loop((p as (rd,rs))::rest, changed, used, done, instrs) = 
	if List.exists (fn r => equal(r, rd)) used then
	   loop(rest, changed, used, p::done, instrs)
	else loop(rest, true, used, done,
                  mv{dst=opnd rd, src=opnd rs}@instrs)
      | loop([], changed, _, done, instrs) = (changed, done, instrs)

    fun cycle([], instrs) = instrs
      | cycle(moves, instrs) =
	(case loop(moves, false, map #2 moves, [], instrs)
	  of (_, [], instrs) => instrs
	   | (true, acc, instrs) => cycle(acc, instrs)
	   | (false, (rd,rs)::acc, instrs) => let
	       fun rename(p as (a,b)) = if equal(rd, b) then (a, TEMP) else p
	       val acc' = (rd, rs) :: map rename acc
	       val instrs' = mv{dst=Option.valOf tmp, src=opnd rd}@instrs
	       val (_, acc'', instrs'') = 
		 loop(acc', false, map #2 acc', [], instrs')
	     in cycle(acc'', instrs'')
	     end
	 (*esac*))

    (* remove moves that have been coalesced. *)
    fun rmvCoalesced(rd::rds, rs::rss) = let
	  val dst = regmap rd
	  val src = regmap rs
	in
	  if dst = src then rmvCoalesced(rds, rss)
	  else (REG dst, REG src)::rmvCoalesced(rds, rss)
	end
      | rmvCoalesced([], []) = []
  in rev (cycle (rmvCoalesced(dst, src), []))
  end
end


root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0