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/psys-ir.sml
ViewVC logotype

View of /trunk/sml3d/src/particles/compiler/psys-ir.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 874 - (download) (annotate)
Thu May 6 18:08:36 2010 UTC (9 years, 4 months ago) by pavelk
File size: 6872 byte(s)
Added a new property to blocks: reference count. This new property is used in an optimization where we remove unused blocks from the program, and inline blocks that only have one reference count to reduce the amount of branching that we need to do.
(* psys-ir.sml
 *
 * COPYRIGHT (c) 2009 John Reppy (http://cs.uchicago.edu/~jhr)
 * All rights reserved.
 *)

structure PSysIR =
  struct
    
    (******** Intermediate Representation *********)  

    datatype const
      = C_VEC of Vec3f.vec3
      | C_FLOAT of Float.float
      | C_BOOL of bool
      | C_INT of int

    fun constToString (C_VEC v) = Vec3f.toString v
      | constToString (C_FLOAT f) = Float.toString f
      | constToString (C_BOOL b) = Bool.toString b
      | constToString (C_INT i) = Int.toString i

    datatype primitive
      (* Vector primitives *)
      = ADD_VEC		(* vector addition *)
      | SUB_VEC		(* vector subtraction *)
      | LEN_SQ		(* length squared *)
      | LEN		(* length *)
      | NORM		(* normalize *)
      | SCALE		(* vector scale *)
      | DOT		(* dot product *)
      | CROSS		(* Cross product *)
      | EXTRACT_X	(* extracts the x-component of a vector *)
      | EXTRACT_Y	(* extracts the y-component of a vector *)
      | EXTRACT_Z	(* extracts the z-component of a vector *)
      | NEG_VEC		(* vector negation *)
  
      (* Scalar Primitives *)
      | ADD		(* scalar addition *)
      | SUB		(* scalar subtraction *)
      | MULT		(* scalar multiplication *)
      | DIV		(* scalar division *)
      | SQRT		(* square root *)
      | COS		(* cosine *)
      | SIN		(* sine *)
      | GEN_VEC		(* create a vector from three floats *)
      
      (* Boolean Primitives *)
      | GT		(* greater than *)
      | EQUALS		(* equality *)
      | AND		(* conjunction *)
      | OR		(* disjunction *)
      | NOT		(* negation *)
      
      (* Utility Primitives *)
      | RAND		(* random number between 0 and 1 *)
      | ITOF		(* convert int to float *)
      | COPY		(* copy one var to another... works with all types *)

    datatype ty = T_VEC | T_FLOAT | T_BOOL | T_INT
    
    datatype block = BLK of {
      id : int,
      params : var list,
      body : stmt,
      visited : bool ref,
      refCount : int ref
    }

    and stmt
      = PRIM of var * primitive * var list * stmt (* Primitives with an argument list *)
      | IF of var * stmt * stmt (* If then else *)
      | RETURN of var list
      | GOTO of block * var list
      | DISCARD

    and var = V of {
	name : string,
	id : int,
	varType : ty,
	scope : scope,
	useCount : int ref,
	useless : bool ref
      }

    and scope
      = S_GLOBAL of PSVar.var_rep
      | S_PARAM
      | S_LOCAL of (primitive * var list) ref
      | S_CONST of const

    datatype renderer
      (* Render it as points *)
      = POINTS
      (* ... *)
      

    datatype program = PGM of {
      emitter : block,
      physics : block list,
      render : renderer
    }

  fun compare(v1 as V{id=id1, ...}, v2 as V{id=id2, ...}) = Int.compare(id1, id2)

    local
      val cnt = ref 0
      fun nextId () = let val n = !cnt in cnt := n+1; n end
    in
    fun new (name, scope, varTy) =
	  V{name = name, id = nextId(), varType = varTy, scope = scope, useCount = ref 0, useless = ref true}
    fun newGlobal (x, varTy) = new (PSVar.name x, S_GLOBAL x, varTy)
    fun newParam (name, varTy) = new (name, S_PARAM, varTy)
    fun newLocal (name, varTy, rhs) = new (name, S_LOCAL (ref rhs), varTy)
    fun newConst (name, c) = let
	  val varTy = (case c
		 of C_VEC _ => T_VEC
		  | C_FLOAT _ => T_FLOAT
		  | C_BOOL _ => T_BOOL
		  | C_INT _ => T_INT
		(* end case *))
	  in
	    new (name, S_CONST c, varTy)
	  end
    end (* local *)

    fun varToString (V{name, id, scope, useCount, ...}) = (case scope
	   of S_GLOBAL _ => String.concat["$", name, "_", Int.toString id, ":", Int.toString (!useCount)]
	    | S_LOCAL(_) => String.concat[name, "_", Int.toString id, ":", Int.toString (!useCount)]
	    | S_CONST c => constToString c
	    | S_PARAM => String.concat["#", name, "_", Int.toString id, ":", Int.toString (!useCount)]
	  (* end case *))

    fun primToString p = (case p
	   of ADD_VEC => "ADD_VEC"
	    | SUB_VEC => "SUB_VEC"
	    | LEN_SQ => "LEN_SQ"
	    | LEN => "LEN"
	    | NORM => "NORM"
	    | SCALE => "SCALE"
	    | DOT => "DOT"
	    | CROSS => "CROSS"
	    | ADD => "ADD"
	    | SUB => "SUB"
	    | MULT => "MULT"
	    | DIV => "DIV"
	    | SQRT => "SQRT"
	    | GT => "GT"
	    | EQUALS => "EQUALS"
	    | AND => "AND"
	    | OR => "OR"
	    | NOT => "NOT"
	    | RAND => "RAND"
	    | ITOF => "ITOF"
	    | COPY => "COPY"
	    | COS => "COS"
	    | SIN => "SIN"
	    | EXTRACT_X	=> "EXTRACT_X"
	    | EXTRACT_Y	=> "EXTRACT_Y"	
	    | EXTRACT_Z	=> "EXTRACT_Z"
	    | GEN_VEC => "GEN_VEC"
	    | NEG_VEC => "NEG_VEC"
	  (* end case *))

    fun constToString (C_VEC v) = Vec3f.toString v
      | constToString (C_FLOAT f) = Float.toString f
      | constToString (C_BOOL b) = Bool.toString b
      | constToString (C_INT i) = Int.toString i

    local
      val cnt = ref 0
    in
     fun newBlock (params, body) = let
       val id = !cnt
      in
       cnt := id + 1;
       BLK{id = id, params = params, body = body, visited = ref false, refCount = ref 0}
      end
    end (* local *)
        
    fun mkPRIM(var, prim, args, stmt) = PRIM(var, prim, args, stmt)
    fun mkIF(x, s1, s2) = IF(x, s1, s2)
    fun mkRETURN(vars) = RETURN(vars)
    fun mkGOTO(blk, vars) = GOTO(blk, vars)    
    fun mkDISCARD () = DISCARD

    fun outputStmt (outS, i, stmt) = let
	  fun pr s = TextIO.output(outS, s)
	  fun prl l = pr(String.concat l)
	  val v2s = varToString
	  fun indent 0 = ()
	    | indent i = (pr "  "; indent(i-1))
	  fun outp (i, stmt) = (case stmt
		  of PRIM(x, p, args, k) => (
		      indent i;
		      prl [
			  v2s x, " = ", primToString p, "(",
			  String.concatWith "," (List.map v2s args),
			  ")\n"
			];
		      outp (i, k))
		  | IF(x, s1, s2) => (
		      indent i;
		      prl ["if ", v2s x, " then\n"];
		      outp (i+1, s1);
		      indent (i); pr "else\n";
		      outp (i+1, s2))
		  | RETURN args => (
		      indent i;
		      prl [
			  "return (",
			  String.concatWith "," (List.map v2s args),
			  ")\n"
			])
		  | GOTO(BLK{id, ...}, args) => (
		      indent i;
		      prl [
			  "goto BLK", Int.toString id, " (",
			  String.concatWith "," (List.map v2s args),
			  ")\n"
			])
		  | DISCARD => (indent i; pr "discard\n")
		(* end case *))
	  in
	    outp (i, stmt)
	  end

    fun output (outS, blocks) = let
	  fun pr s = TextIO.output(outS, s)
	  fun prl l = pr(String.concat l)
	  val v2s = varToString
      
	   fun prBlk (BLK{id, params, body, ...}) = (
		prl [
		    "\nBLK", Int.toString id, " (",
		    String.concatWith "," (List.map v2s params),
		    "):\n"
		  ];
		outputStmt (outS, 2, body))
	  in
	    List.app prBlk blocks
	  end

    fun outputPgm(outS, pgm as PGM{emitter, physics, ...}) = (
      TextIO.output(outS, "Emitter:\n");
      output(outS, [emitter]);
      TextIO.output(outS, "\n\nPhysics:\n");
      output(outS, physics)
    )

  end (* PSysIR *)

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