Home My Page Projects Code Snippets Project Openings 3D graphics for Standard ML
Summary Activity SCM

SCM Repository

[sml3d] View of /trunk/sml3d/src/particles/compiler/unused.sml
ViewVC logotype

View of /trunk/sml3d/src/particles/compiler/unused.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 906 - (download) (annotate)
Wed Jun 2 21:13:39 2010 UTC (9 years, 5 months ago) by pavelk
File size: 3695 byte(s)
Switched program representation to not be a list of blocks. Rather, we reference just one block and use the tree representation when doing our analysis. Hence we now have a much more robust system for error checking, etc. Hopefully this fixes the problem of having inconsistencies between our blocks.
(* Unused variable elimination.
 * 
 * Get rid of all of the variables that aren't being used by any of the
 * succeeding statements. Should be done after constant folding to maximize
 * efficiency.
 *)
structure RemoveUnused :> PSYSIR_OPTIMIZATION = 
  struct

  val gProgramChanged = ref false;
  structure IR = PSysIR

  fun resetVarRefCount(block as IR.BLK{body, params, ...}) = let
    fun resetVar(IR.V{useCount, ...}) = useCount := 0
    fun resetStmt(IR.PRIM(v, p, vl, s)) = (
         resetVar(v);
         List.app resetVar vl;
         resetStmt(s))
      | resetStmt(IR.IF(v, s1, s2)) = (
         resetVar(v);
         resetStmt(s1);
         resetStmt(s2))
      | resetStmt(IR.GOTO(block, vl)) = (
         resetVarRefCount(block);
         List.app resetVar vl)
      | resetStmt(IR.RETURN(vl, svars)) = List.app resetVar vl
      | resetStmt(_) = ()
   in
    List.app resetVar params;
    resetStmt(body)
   end
 
  val countedSet = ref (IR.IDSet.empty)
  fun countVarReferences(block as IR.BLK{body, ...}) = let
    fun updateVar(IR.V{useCount, ...}) = useCount := (!useCount) + 1
    fun updateStmt(IR.PRIM(var, prim, vl, stmt)) = (
        List.app updateVar vl;
        updateStmt(stmt))
      | updateStmt(IR.IF(var, s1, s2)) = (
        updateVar(var);
        updateStmt(s1);
        updateStmt(s2))
      | updateStmt(IR.GOTO(blk as IR.BLK{id, ...}, vl)) = 
         if IR.IDSet.member(!countedSet, id) then 
           List.app updateVar vl
         else (
           List.app updateVar vl;
           countedSet := (IR.IDSet.add(!countedSet, id));
           countVarReferences(blk)
         )
      | updateStmt(IR.RETURN(vl, svars)) = List.app updateVar vl
      | updateStmt(_) = ()
   in
    updateStmt(body);
    ()
   end (*countVarReferences*)
  
  fun printErr s = TextIO.output(TextIO.stdErr, s ^ "\n")
  fun prv(var as IR.V{name, useCount, ...}) = 
    printErr (String.concat([name, ": ", Int.toString (!useCount)]))

  fun prRefCt(IR.PRIM(v, p, vl, stmt)) = (prv(v); prRefCt(stmt))
    | prRefCt(IR.IF(v, s1, s2)) = (prRefCt(s1); prRefCt(s2))
    | prRefCt(_) = ()

  fun prRefCtForBlk(IR.BLK{body, ...}) = prRefCt(body)
  
  fun removeUnused(rootBlk as IR.BLK{id=rootID, ...}) = let
    fun isUnused(v as IR.V{useCount, name, ...}) = 
      if !useCount > 0 then 
        false 
      else 
        true

    fun removeUnusedInBlock(IR.BLK{id, params, body, visited, refCount}) = let
      fun removeUnusedStmt(IR.PRIM(v as IR.V{name, ...}, p, vl, s)) =
          if isUnused(v) then
	    (gProgramChanged := true;
	    (* TextIO.output(TextIO.stdErr, "Removing variable: " ^ name ^ "\n"); *) 
            removeUnusedStmt(s))
          else 
            IR.PRIM(v, p, vl, removeUnusedStmt(s))
        | removeUnusedStmt(IR.IF(var, s1, s2)) = 
          IR.IF(var, removeUnusedStmt(s1), removeUnusedStmt(s2))
        | removeUnusedStmt(IR.GOTO(blk, vl)) = IR.GOTO(removeUnusedInBlock(blk), vl)
        | removeUnusedStmt(x) = x
     in
      IR.BLK{id=id, params=params, body=removeUnusedStmt(body), visited=visited, refCount=refCount}
     end

    val _ = resetVarRefCount(rootBlk)
    (* val _ = List.app prRefCtForBlk (IR.extractBlockList rootBlk) *)
    val _ = countedSet := (IR.IDSet.add(IR.IDSet.empty, rootID))
    val _ = countVarReferences(rootBlk)
    val _ = gProgramChanged := false
    val optimizedBlock = removeUnusedInBlock rootBlk
   in
    if (!gProgramChanged) then 
      removeUnused(optimizedBlock) 
    else 
      optimizedBlock
   end (* removeUnused *)

  fun optimize (pgm as IR.PGM{emitter, physics, render}) = IR.PGM {
    emitter = removeUnused(emitter),
    physics = removeUnused(physics),
    render = render
  }

 end

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