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

SCM Repository

[diderot] View of /branches/vis15/src/compiler/cfg-ir/rewrite-fn.sml
ViewVC logotype

View of /branches/vis15/src/compiler/cfg-ir/rewrite-fn.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3517 - (download) (annotate)
Sat Dec 19 04:39:21 2015 UTC (3 years, 8 months ago) by jhr
File size: 4350 byte(s)
working on merge
(* rewrite-fn.sml
 *
 * This code is part of the Diderot Project (http://diderot-language.cs.uchicago.edu)
 *
 * COPYRIGHT (c) 2015 The University of Chicago
 * All rights reserved.
 *
 * Infrastructure for rewriting the CFG.
 *)

signature REWRITE = sig
    structure IR : SSA
  (* rewrite the right-hand-side of an assignment; returns NONE if there are no changes
   * and SOME assigns if the assignment is rewritten to the assigns list.
   *)
    val doAssign : IR.assign -> (IR.var * IR.rhs) list option
  (* rewrite the rhs of an multi-assignment *)
    val doMAssign : IR.massign -> (IR.var * IR.rhs) list option
  (* eliminates unused variables; returns true if any changes *)
    val elimUnusedVars : IR.cfg -> bool
  end

functor RewriteFn (R : REWRITE) : sig

    val transform : R.IR.program -> R.IR.program

  end = struct

    open R

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

  (* simplify assignment and multi-assignment statements *)
    fun simplify nd = let
          fun rewrite (SOME[]) = (IR.CFG.deleteNode nd; true)
            | rewrite (SOME assigns) = let
                val assigns = List.map
                      (fn (y, rhs) => (IR.Var.setBinding(y, IR.VB_RHS rhs); IR.ASSGN(y, rhs)))
                        assigns
                in
                  IR.CFG.replaceNodeWithCFG (nd, IR.CFG.mkBlock assigns);
                  true
                end
            | rewrite NONE = false
          in
            case IR.Node.kind nd
             of IR.ASSIGN{stm=(y, rhs), ...} => if (useCount y = 0)
                  then false (* skip unused assignments *)
                  else rewrite (doAssign (y, rhs))
              | IR.MASSIGN{stm, ...} => rewrite (doMAssign stm)
              | _ => false
            (* end case *)
          end

    fun loopToFixPt f = let
          fun loop anyChanges = if f() then loop true else anyChanges
          in
            loop false
          end

    fun transform prog = let
	  val IR.Program{
		  props, consts, inputs, constInit, globals, globalInit, strand, create, update
		} = prog
          fun simplifyCFG cfg = let
                val changed = ref false
                fun simplify' nd = if simplify nd then changed := true else ()
                in
                  IR.CFG.apply simplify' cfg;
                  !changed
                end
          fun doCFG cfg = let
                val changes = loopToFixPt (fn () => simplifyCFG cfg)
                val changes = loopToFixPt (fn () => elimUnusedVars cfg) orelse changes
                in
                  changes
                end
	  fun doOptionalCFG (NONE, changes) = changes
	    | doOptionalCFG (SOME cfg, changes) = doCFG cfg orelse changes
          fun doCreate (IR.Create{code, ...}) =
                loopToFixPt (fn () => elimUnusedVars code)
          fun doStrand (IR.Strand{stateInit, initM, updateM, stabilizeM, ...}) = let
                val changes = doCFG stateInit
                val changes = doOptionalCFG (initM, changes)
		val changes = doCFG updateM orelse changes
		val changes = doOptionalCFG (stabilizeM, changes)
                in
                  changes
                end
          fun optPass () = let
                val changes = doCFG constInit
                val changes = doCFG globalInit
                val changes = doCreate create orelse changes
                val changes = doStrand strand orelse changes
		val changes = doOptionalCFG (update, changes)
                in
                  changes
                end
        (* filter out unused globals and update the program properties if necessary *)
(* FIXME: what about consts and inputs? *)
          val (props, globals) = (case (globals, List.filter (fn x => IR.GlobalVar.useCount x > 0) globals)
                 of ([], _) => (props, globals)
                  | (_, []) => (Properties.clearProp Properties.HasGlobals props, [])
                  | (_, liveGlobals) => (props, liveGlobals)
                (* end case *))
          in
            loopToFixPt optPass;
            IR.Program{
                props = props,
		consts = consts,
		inputs = inputs,
		constInit = constInit,
                globals = globals,
                globalInit = globalInit,
                create = create,
                strand = strand,
		update = update
              }
          end

  end

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