Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] View of /branches/pure-cfg/src/compiler/high-il/high-opt.sml
ViewVC logotype

View of /branches/pure-cfg/src/compiler/high-il/high-opt.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 372 - (download) (annotate)
Sun Oct 3 15:20:28 2010 UTC (9 years ago) by jhr
Original Path: trunk/src/compiler/high-il/high-opt.sml
File size: 4840 byte(s)
  Bug fixes to HigiIL optimization
(* high-opt.sml
 *
 * COPYRIGHT (c) 2010 The Diderot Project (http://diderot.cs.uchicago.edu)
 * All rights reserved.
 *
 * Optimization of the HighIL representation of Diderot terms.  The main
 * task of this phase is to statically resolve field definitions.
 *)

structure HighOptimizer : sig

    val optimize : HighIL.program -> HighIL.program

  end = struct

    structure IL = HighIL
    structure Op = HighOps
    structure V = IL.Var
    structure ST = Stats
    structure F = FieldDef

    structure Census = CensusFn (IL)

  (********** Counters for statistics **********)
    val cntConstConvolve	= ST.newCounter "high-opt:const-convolve"
    val cntConstField		= ST.newCounter "high-opt:const-field"
    val cntConstDiff		= ST.newCounter "high-opt:const-diff"
    val cntUnused		= ST.newCounter "high-opt:unused"
    val firstCounter            = cntConstConvolve
    val lastCounter             = cntUnused

    fun useCount (IL.V{useCnt, ...}) = !useCnt

  (* decrement a variable's use count *)
    fun decUse (IL.V{useCnt, ...}) = (useCnt := !useCnt - 1)

    fun getRHS x = (case V.binding x
	   of IL.VB_RHS(IL.OP arg) => SOME arg
	    | _ => NONE
	  (* end case *))

  (* optimize the rhs of an assignment, returning NONE if there is no change *)
    fun doRHS rhs = (case rhs
	   of IL.OP(Op.Convolve, [v, h]) => (case (getRHS v, getRHS h)
		 of (SOME(Op.LoadImage v', []), SOME(Op.Kernel h', [])) => (
		      ST.tick cntConstConvolve;
		      decUse v; decUse h;
		      SOME(IL.OP(Op.Field(F.convolve(v', h')), [])))
		  | _ => raise Fail "non-constant Convolve"
		(* end case *))
	    | IL.OP(Op.AddField, [f, g]) => (case (getRHS f, getRHS g)
		 of (SOME(Op.Field f', []), SOME(Op.Field g', [])) => (
		      ST.tick cntConstField;
		      decUse f; decUse g;
		      SOME(IL.OP(Op.Field(F.SUM(f', g')), [])))
		  | _ => NONE
		(* end case *))
	    | IL.OP(Op.NegField, [f]) => (case (getRHS f)
		 of SOME(Op.Field f', []) => (
		      ST.tick cntConstField;
		      decUse f;
		      SOME(IL.OP(Op.Field(F.neg f'), [])))
		  | _ => NONE
		(* end case *))
	    | IL.OP(Op.DiffField, [f]) => (case (getRHS f)
		 of SOME(Op.Field f', []) => (
		      ST.tick cntConstDiff;
		      decUse f;
		      SOME(IL.OP(Op.Field(F.diff f'), [])))
		  | _ => raise Fail "non-constant DiffField"
		(* end case *))
	    | _ => NONE
	  (* end case *))

  (* simplify expressions *)
    fun simplify nodes = let
	  fun doAssign (y, rhs) = (case doRHS rhs
		 of SOME rhs' => (V.setBinding(y, IL.VB_RHS rhs'); (y, rhs'))
		  | NONE => (y, rhs)
		(* end case *))
	  fun doNode (IL.ND{kind=IL.BLOCK{body, ...}, ...}) =
		body := List.map doAssign (!body)
	    | doNode _ = ()
	  in
	    List.app doNode nodes
	  end

  (* reduce the code by removing variables with use counts of 0 *)
    fun reduce nodes = let
	  fun checkVar (y, _) = (useCount y > 0) orelse (ST.tick cntUnused; false)
	  fun doNode (IL.ND{kind, ...}) = (case kind
		 of IL.JOIN{phis, ...} => let
		      fun doVar (y, xs) = if (useCount y = 0)
			    then (
			      ST.tick cntUnused;
			      List.app decUse xs;
			      false)
			    else true
		      in
			phis := List.filter doVar (!phis)
		      end
		  | IL.BLOCK{body, ...} => let
		    (* check for unused lhs variables in reverse order *)
		      fun doAssigns [] = []
			| doAssigns ((y, rhs)::r) = let
			    val r = doAssigns r
			    in
			      if (useCount y = 0)
				then (
				  ST.tick cntUnused;
				  case rhs
				   of IL.VAR x => decUse x
				    | IL.LIT _ => ()
				    | IL.OP(_, xs) => List.app decUse xs
				    | IL.CONS xs => List.app decUse xs
				  (* end case *);
				  r)
				else (y, rhs)::r
			    end
		      in
			body := doAssigns (!body)
		      end
		  | _ => ()
		(* end case *))
	  in
	    List.app doNode (List.rev nodes)
	  end

    fun loopToFixPt f prog = let
	  fun loop (n, prog) = let
		val () = f prog
		val n' = Stats.sum{from=firstCounter, to=lastCounter}
		in
		  if (n = n') then () else loop(n', prog)
		end
	  in
	    loop (Stats.sum{from=firstCounter, to=lastCounter}, prog)
	  end

    fun optimize (prog as IL.Program{globals, globalInit, actors}) = let
	  val _ = Census.init prog
	  fun doStmt stm = let
		val nodes = IL.sortNodes stm
		in
		  loopToFixPt simplify nodes;
		  loopToFixPt reduce nodes;
		  nodes
		end
	  val globInitNodes = doStmt globalInit
	  fun doMethod (IL.Method{body, ...}) = let
		val nodes = IL.sortNodes body
		in
		  loopToFixPt simplify nodes;
		  loopToFixPt reduce nodes
		end
	  fun doActor (IL.Actor{stateInit, methods, ...}) = let
		val nodes = IL.sortNodes stateInit
		in
		  loopToFixPt simplify nodes;
		  loopToFixPt reduce nodes;
		  List.app doMethod methods
		end
	  val _ = List.app doActor actors
	  in
	    IL.Program{
		globals = globals,
		globalInit = globalInit,
		actors = actors
	      }
	  end

  end

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